aggas.pas 54 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556
  1. {
  2. Copyright (c) 1998-2006 by the Free Pascal team
  3. This unit implements the generic part of the GNU assembler
  4. (v2.8 or later) writer
  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. { Base unit for writing GNU assembler output.
  19. }
  20. unit aggas;
  21. {$i fpcdefs.inc}
  22. interface
  23. uses
  24. cclasses,
  25. globtype,globals,
  26. aasmbase,aasmtai,aasmdata,aasmcpu,
  27. assemble;
  28. type
  29. TCPUInstrWriter = class;
  30. {# This is a derived class which is used to write
  31. GAS styled assembler.
  32. }
  33. { TGNUAssembler }
  34. TGNUAssembler=class(texternalassembler)
  35. protected
  36. function sectionname(atype:TAsmSectiontype;const aname:string;aorder:TAsmSectionOrder):string;virtual;
  37. procedure WriteSection(atype:TAsmSectiontype;const aname:string;aorder:TAsmSectionOrder);
  38. procedure WriteExtraHeader;virtual;
  39. procedure WriteInstruction(hp: tai);
  40. procedure WriteWeakSymbolDef(s: tasmsymbol); virtual;
  41. public
  42. function MakeCmdLine: TCmdStr; override;
  43. procedure WriteTree(p:TAsmList);override;
  44. procedure WriteAsmList;override;
  45. destructor destroy; override;
  46. private
  47. setcount: longint;
  48. procedure WriteDecodedSleb128(a: int64);
  49. procedure WriteDecodedUleb128(a: qword);
  50. function NextSetLabel: string;
  51. protected
  52. InstrWriter: TCPUInstrWriter;
  53. end;
  54. {# This is the base class for writing instructions.
  55. The WriteInstruction() method must be overridden
  56. to write a single instruction to the assembler
  57. file.
  58. }
  59. TCPUInstrWriter = class
  60. constructor create(_owner: TGNUAssembler);
  61. procedure WriteInstruction(hp : tai); virtual; abstract;
  62. protected
  63. owner: TGNUAssembler;
  64. end;
  65. { TAppleGNUAssembler }
  66. TAppleGNUAssembler=class(TGNUAssembler)
  67. protected
  68. function sectionname(atype:TAsmSectiontype;const aname:string;aorder:TAsmSectionOrder):string;override;
  69. procedure WriteWeakSymbolDef(s: tasmsymbol); override;
  70. end;
  71. TAoutGNUAssembler=class(TGNUAssembler)
  72. function sectionname(atype:TAsmSectiontype;const aname:string;aorder:TAsmSectionOrder):string;override;
  73. end;
  74. implementation
  75. uses
  76. SysUtils,
  77. cutils,cfileutl,systems,
  78. fmodule,finput,verbose,
  79. itcpugas,cpubase
  80. ;
  81. const
  82. line_length = 70;
  83. var
  84. symendcount : longint;
  85. type
  86. {$ifdef cpuextended}
  87. t80bitarray = array[0..9] of byte;
  88. {$endif cpuextended}
  89. t64bitarray = array[0..7] of byte;
  90. t32bitarray = array[0..3] of byte;
  91. {****************************************************************************}
  92. { Support routines }
  93. {****************************************************************************}
  94. function fixline(s:string):string;
  95. {
  96. return s with all leading and ending spaces and tabs removed
  97. }
  98. var
  99. i,j,k : integer;
  100. begin
  101. i:=length(s);
  102. while (i>0) and (s[i] in [#9,' ']) do
  103. dec(i);
  104. j:=1;
  105. while (j<i) and (s[j] in [#9,' ']) do
  106. inc(j);
  107. for k:=j to i do
  108. if s[k] in [#0..#31,#127..#255] then
  109. s[k]:='.';
  110. fixline:=Copy(s,j,i-j+1);
  111. end;
  112. function single2str(d : single) : string;
  113. var
  114. hs : string;
  115. begin
  116. str(d,hs);
  117. { replace space with + }
  118. if hs[1]=' ' then
  119. hs[1]:='+';
  120. single2str:='0d'+hs
  121. end;
  122. function double2str(d : double) : string;
  123. var
  124. hs : string;
  125. begin
  126. str(d,hs);
  127. { replace space with + }
  128. if hs[1]=' ' then
  129. hs[1]:='+';
  130. double2str:='0d'+hs
  131. end;
  132. function extended2str(e : extended) : string;
  133. var
  134. hs : string;
  135. begin
  136. str(e,hs);
  137. { replace space with + }
  138. if hs[1]=' ' then
  139. hs[1]:='+';
  140. extended2str:='0d'+hs
  141. end;
  142. { convert floating point values }
  143. { to correct endian }
  144. procedure swap64bitarray(var t: t64bitarray);
  145. var
  146. b: byte;
  147. begin
  148. b:= t[7];
  149. t[7] := t[0];
  150. t[0] := b;
  151. b := t[6];
  152. t[6] := t[1];
  153. t[1] := b;
  154. b:= t[5];
  155. t[5] := t[2];
  156. t[2] := b;
  157. b:= t[4];
  158. t[4] := t[3];
  159. t[3] := b;
  160. end;
  161. procedure swap32bitarray(var t: t32bitarray);
  162. var
  163. b: byte;
  164. begin
  165. b:= t[1];
  166. t[1]:= t[2];
  167. t[2]:= b;
  168. b:= t[0];
  169. t[0]:= t[3];
  170. t[3]:= b;
  171. end;
  172. const
  173. ait_const2str : array[aitconst_128bit..aitconst_darwin_dwarf_delta32] of string[20]=(
  174. #9'.fixme128'#9,#9'.quad'#9,#9'.long'#9,#9'.short'#9,#9'.byte'#9,
  175. #9'.sleb128'#9,#9'.uleb128'#9,
  176. #9'.rva'#9,#9'.secrel32'#9,#9'.quad'#9,#9'.long'#9
  177. );
  178. {****************************************************************************}
  179. { GNU Assembler writer }
  180. {****************************************************************************}
  181. destructor TGNUAssembler.Destroy;
  182. begin
  183. InstrWriter.free;
  184. inherited destroy;
  185. end;
  186. function TGNUAssembler.MakeCmdLine: TCmdStr;
  187. begin
  188. result := inherited MakeCmdLine;
  189. // MWE: disabled again. It generates dwarf info for the generated .s
  190. // files as well. This conflicts with the info we generate
  191. // if target_dbg.id = dbg_dwarf then
  192. // result := result + ' --gdwarf-2';
  193. end;
  194. function TGNUAssembler.NextSetLabel: string;
  195. begin
  196. inc(setcount);
  197. result := target_asm.labelprefix+'$set$'+tostr(setcount);
  198. end;
  199. function TGNUAssembler.sectionname(atype:TAsmSectiontype;const aname:string;aorder:TAsmSectionOrder):string;
  200. const
  201. secnames : array[TAsmSectiontype] of string[length('__DATA, __datacoal_nt,coalesced')] = ('',
  202. '.text',
  203. '.data',
  204. { why doesn't .rodata work? (FK) }
  205. { sometimes we have to create a data.rel.ro instead of .rodata, e.g. for }
  206. { vtables (and anything else containing relocations), otherwise those are }
  207. { not relocated properly on e.g. linux/ppc64. g++ generates there for a }
  208. { vtable for a class called Window: }
  209. { .section .data.rel.ro._ZTV6Window,"awG",@progbits,_ZTV6Window,comdat }
  210. { TODO: .data.ro not yet working}
  211. {$if defined(arm) or defined(powerpc)}
  212. '.rodata',
  213. {$else arm}
  214. '.data',
  215. {$endif arm}
  216. {$if defined(m68k)} { Amiga/m68k GNU AS doesn't seem to like .rodata (KB) }
  217. '.data',
  218. {$else}
  219. '.rodata',
  220. {$endif}
  221. '.bss',
  222. '.threadvar',
  223. '.pdata',
  224. '', { stubs }
  225. '__DATA,__nl_symbol_ptr',
  226. '__DATA,__la_symbol_ptr',
  227. '__DATA,__mod_init_func',
  228. '__DATA,__mod_term_func',
  229. '.stab',
  230. '.stabstr',
  231. '.idata$2','.idata$4','.idata$5','.idata$6','.idata$7','.edata',
  232. '.eh_frame',
  233. '.debug_frame','.debug_info','.debug_line','.debug_abbrev',
  234. '.fpc',
  235. '.toc',
  236. '.init',
  237. '.fini',
  238. '.objc_class',
  239. '.objc_meta_class',
  240. '.objc_cat_cls_meth',
  241. '.objc_cat_inst_meth',
  242. '.objc_protocol',
  243. '.objc_string_object',
  244. '.objc_cls_meth',
  245. '.objc_inst_meth',
  246. '.objc_cls_refs',
  247. '.objc_message_refs',
  248. '.objc_symbols',
  249. '.objc_category',
  250. '.objc_class_vars',
  251. '.objc_instance_vars',
  252. '.objc_module_info',
  253. '.objc_class_names',
  254. '.objc_meth_var_types',
  255. '.objc_meth_var_names',
  256. '.objc_selector_strs',
  257. '.objc_protocol_ext',
  258. '.objc_class_ext',
  259. '.objc_property',
  260. '.objc_image_info',
  261. '.objc_cstring_object',
  262. '.objc_sel_fixup',
  263. '__DATA,__objc_data',
  264. '__DATA,__objc_const',
  265. '.objc_superrefs',
  266. '__DATA, __datacoal_nt,coalesced',
  267. '.objc_classlist',
  268. '.objc_nlclasslist',
  269. '.objc_catlist',
  270. '.obcj_nlcatlist',
  271. '.objc_protolist'
  272. );
  273. secnames_pic : array[TAsmSectiontype] of string[length('__DATA, __datacoal_nt,coalesced')] = ('',
  274. '.text',
  275. '.data.rel',
  276. '.data.rel',
  277. '.data.rel',
  278. '.bss',
  279. '.threadvar',
  280. '.pdata',
  281. '', { stubs }
  282. '__DATA,__nl_symbol_ptr',
  283. '__DATA,__la_symbol_ptr',
  284. '__DATA,__mod_init_func',
  285. '__DATA,__mod_term_func',
  286. '.stab',
  287. '.stabstr',
  288. '.idata$2','.idata$4','.idata$5','.idata$6','.idata$7','.edata',
  289. '.eh_frame',
  290. '.debug_frame','.debug_info','.debug_line','.debug_abbrev',
  291. '.fpc',
  292. '.toc',
  293. '.init',
  294. '.fini',
  295. '.objc_class',
  296. '.objc_meta_class',
  297. '.objc_cat_cls_meth',
  298. '.objc_cat_inst_meth',
  299. '.objc_protocol',
  300. '.objc_string_object',
  301. '.objc_cls_meth',
  302. '.objc_inst_meth',
  303. '.objc_cls_refs',
  304. '.objc_message_refs',
  305. '.objc_symbols',
  306. '.objc_category',
  307. '.objc_class_vars',
  308. '.objc_instance_vars',
  309. '.objc_module_info',
  310. '.objc_class_names',
  311. '.objc_meth_var_types',
  312. '.objc_meth_var_names',
  313. '.objc_selector_strs',
  314. '.objc_protocol_ext',
  315. '.objc_class_ext',
  316. '.objc_property',
  317. '.objc_image_info',
  318. '.objc_cstring_object',
  319. '.objc_sel_fixup',
  320. '__DATA, __objc_data',
  321. '__DATA, __objc_const',
  322. '.objc_superrefs',
  323. '__DATA, __datacoal_nt,coalesced',
  324. '.objc_classlist',
  325. '.objc_nlclasslist',
  326. '.objc_catlist',
  327. '.obcj_nlcatlist',
  328. '.objc_protolist'
  329. );
  330. var
  331. sep : string[3];
  332. secname : string;
  333. begin
  334. if (cs_create_pic in current_settings.moduleswitches) and
  335. not(target_info.system in systems_darwin) then
  336. secname:=secnames_pic[atype]
  337. else
  338. secname:=secnames[atype];
  339. {$ifdef m68k}
  340. { old Amiga GNU AS doesn't support .section .fpc }
  341. if (atype=sec_fpc) and (target_info.system = system_m68k_amiga) then
  342. secname:=secnames[sec_data];
  343. {$endif}
  344. if (atype=sec_fpc) and (Copy(aname,1,3)='res') then
  345. begin
  346. result:=secname+'.'+aname;
  347. exit;
  348. end;
  349. if (atype=sec_threadvar) and
  350. (target_info.system=system_i386_win32) then
  351. secname:='.tls';
  352. { go32v2 stub only loads .text and .data sections, and allocates space for .bss.
  353. Thus, data which normally goes into .rodata and .rodata_norel sections must
  354. end up in .data section }
  355. if (atype in [sec_rodata,sec_rodata_norel]) and
  356. (target_info.system=system_i386_go32v2) then
  357. secname:='.data';
  358. { For bss we need to set some flags that are target dependent,
  359. it is easier to disable it for smartlinking. It doesn't take up
  360. filespace }
  361. if not(target_info.system in systems_darwin) and
  362. create_smartlink_sections and
  363. (aname<>'') and
  364. (atype<>sec_toc) and
  365. { on embedded systems every byte counts, so smartlink bss too }
  366. ((atype<>sec_bss) or (target_info.system in systems_embedded)) then
  367. begin
  368. case aorder of
  369. secorder_begin :
  370. sep:='.b_';
  371. secorder_end :
  372. sep:='.z_';
  373. else
  374. sep:='.n_';
  375. end;
  376. result:=secname+sep+aname
  377. end
  378. else
  379. result:=secname;
  380. end;
  381. procedure TGNUAssembler.WriteSection(atype:TAsmSectiontype;const aname:string;aorder:TAsmSectionOrder);
  382. var
  383. s : string;
  384. begin
  385. AsmLn;
  386. case target_info.system of
  387. system_i386_OS2,
  388. system_i386_EMX,
  389. system_m68k_amiga, { amiga has old GNU AS (2.14), which blews up from .section (KB) }
  390. system_m68k_linux: ;
  391. system_powerpc_darwin,
  392. system_i386_darwin,
  393. system_i386_iphonesim,
  394. system_powerpc64_darwin,
  395. system_x86_64_darwin,
  396. system_arm_darwin:
  397. begin
  398. if (atype in [sec_stub,sec_objc_data,sec_objc_const,sec_data_coalesced]) then
  399. AsmWrite('.section ');
  400. end
  401. else
  402. AsmWrite('.section ');
  403. end;
  404. s:=sectionname(atype,aname,aorder);
  405. AsmWrite(s);
  406. case atype of
  407. sec_fpc :
  408. if aname = 'resptrs' then
  409. AsmWrite(', "a", @progbits');
  410. sec_stub :
  411. begin
  412. case target_info.system of
  413. { there are processor-independent shortcuts available }
  414. { for this, namely .symbol_stub and .picsymbol_stub, but }
  415. { they don't work and gcc doesn't use them either... }
  416. system_powerpc_darwin,
  417. system_powerpc64_darwin:
  418. if (cs_create_pic in current_settings.moduleswitches) then
  419. AsmWriteln('__TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32')
  420. else
  421. AsmWriteln('__TEXT,__symbol_stub1,symbol_stubs,pure_instructions,16');
  422. system_i386_darwin,
  423. system_i386_iphonesim:
  424. AsmWriteln('__IMPORT,__jump_table,symbol_stubs,self_modifying_code+pure_instructions,5');
  425. system_arm_darwin:
  426. if (cs_create_pic in current_settings.moduleswitches) then
  427. AsmWriteln('.section __TEXT,__picsymbolstub4,symbol_stubs,none,16')
  428. else
  429. AsmWriteln('.section __TEXT,__symbol_stub4,symbol_stubs,none,12')
  430. { darwin/x86-64 uses RIP-based GOT addressing, no symbol stubs }
  431. else
  432. internalerror(2006031101);
  433. end;
  434. end;
  435. end;
  436. AsmLn;
  437. LastSecType:=atype;
  438. end;
  439. procedure TGNUAssembler.WriteDecodedUleb128(a: qword);
  440. var
  441. i,len : longint;
  442. buf : array[0..63] of byte;
  443. begin
  444. len:=EncodeUleb128(a,buf);
  445. for i:=0 to len-1 do
  446. begin
  447. if (i > 0) then
  448. AsmWrite(',');
  449. AsmWrite(tostr(buf[i]));
  450. end;
  451. end;
  452. procedure TGNUAssembler.WriteDecodedSleb128(a: int64);
  453. var
  454. i,len : longint;
  455. buf : array[0..255] of byte;
  456. begin
  457. len:=EncodeSleb128(a,buf);
  458. for i:=0 to len-1 do
  459. begin
  460. if (i > 0) then
  461. AsmWrite(',');
  462. AsmWrite(tostr(buf[i]));
  463. end;
  464. end;
  465. procedure TGNUAssembler.WriteTree(p:TAsmList);
  466. function needsObject(hp : tai_symbol) : boolean;
  467. begin
  468. needsObject :=
  469. (
  470. assigned(hp.next) and
  471. (tai(hp.next).typ in [ait_const,ait_datablock,
  472. ait_real_32bit,ait_real_64bit,ait_real_80bit,ait_comp_64bit])
  473. ) or
  474. (hp.sym.typ=AT_DATA);
  475. end;
  476. procedure doalign(alignment: byte; use_op: boolean; fillop: byte; out last_align: longint);
  477. var
  478. i: longint;
  479. begin
  480. last_align:=alignment;
  481. if alignment>1 then
  482. begin
  483. if not(target_info.system in systems_darwin) then
  484. begin
  485. AsmWrite(#9'.balign '+tostr(alignment));
  486. if use_op then
  487. AsmWrite(','+tostr(fillop))
  488. {$ifdef x86}
  489. { force NOP as alignment op code }
  490. else if LastSecType=sec_code then
  491. AsmWrite(',0x90');
  492. {$endif x86}
  493. end
  494. else
  495. begin
  496. { darwin as only supports .align }
  497. if not ispowerof2(alignment,i) then
  498. internalerror(2003010305);
  499. AsmWrite(#9'.align '+tostr(i));
  500. last_align:=i;
  501. end;
  502. AsmLn;
  503. end;
  504. end;
  505. var
  506. ch : char;
  507. hp : tai;
  508. hp1 : tailineinfo;
  509. constdef : taiconst_type;
  510. s,t : string;
  511. i,pos,l : longint;
  512. InlineLevel : longint;
  513. last_align : longint;
  514. co : comp;
  515. sin : single;
  516. d : double;
  517. {$ifdef cpuextended}
  518. e : extended;
  519. {$endif cpuextended}
  520. do_line : boolean;
  521. sepChar : char;
  522. begin
  523. if not assigned(p) then
  524. exit;
  525. last_align := 2;
  526. InlineLevel:=0;
  527. { lineinfo is only needed for al_procedures (PFV) }
  528. do_line:=(cs_asm_source in current_settings.globalswitches) or
  529. ((cs_lineinfo in current_settings.moduleswitches)
  530. and (p=current_asmdata.asmlists[al_procedures]));
  531. hp:=tai(p.first);
  532. while assigned(hp) do
  533. begin
  534. prefetch(pointer(hp.next)^);
  535. if not(hp.typ in SkipLineInfo) then
  536. begin
  537. hp1 := hp as tailineinfo;
  538. current_filepos:=hp1.fileinfo;
  539. { no line info for inlined code }
  540. if do_line and (inlinelevel=0) then
  541. begin
  542. { load infile }
  543. if lastfileinfo.fileindex<>hp1.fileinfo.fileindex then
  544. begin
  545. infile:=current_module.sourcefiles.get_file(hp1.fileinfo.fileindex);
  546. if assigned(infile) then
  547. begin
  548. { open only if needed !! }
  549. if (cs_asm_source in current_settings.globalswitches) then
  550. infile.open;
  551. end;
  552. { avoid unnecessary reopens of the same file !! }
  553. lastfileinfo.fileindex:=hp1.fileinfo.fileindex;
  554. { be sure to change line !! }
  555. lastfileinfo.line:=-1;
  556. end;
  557. { write source }
  558. if (cs_asm_source in current_settings.globalswitches) and
  559. assigned(infile) then
  560. begin
  561. if (infile<>lastinfile) then
  562. begin
  563. AsmWriteLn(target_asm.comment+'['+infile.name^+']');
  564. if assigned(lastinfile) then
  565. lastinfile.close;
  566. end;
  567. if (hp1.fileinfo.line<>lastfileinfo.line) and
  568. ((hp1.fileinfo.line<infile.maxlinebuf) or (InlineLevel>0)) then
  569. begin
  570. if (hp1.fileinfo.line<>0) and
  571. ((infile.linebuf^[hp1.fileinfo.line]>=0) or (InlineLevel>0)) then
  572. AsmWriteLn(target_asm.comment+'['+tostr(hp1.fileinfo.line)+'] '+
  573. fixline(infile.GetLineStr(hp1.fileinfo.line)));
  574. { set it to a negative value !
  575. to make that is has been read already !! PM }
  576. if (infile.linebuf^[hp1.fileinfo.line]>=0) then
  577. infile.linebuf^[hp1.fileinfo.line]:=-infile.linebuf^[hp1.fileinfo.line]-1;
  578. end;
  579. end;
  580. lastfileinfo:=hp1.fileinfo;
  581. lastinfile:=infile;
  582. end;
  583. end;
  584. case hp.typ of
  585. ait_comment :
  586. Begin
  587. AsmWrite(target_asm.comment);
  588. AsmWritePChar(tai_comment(hp).str);
  589. AsmLn;
  590. End;
  591. ait_regalloc :
  592. begin
  593. if (cs_asm_regalloc in current_settings.globalswitches) then
  594. begin
  595. AsmWrite(#9+target_asm.comment+'Register ');
  596. repeat
  597. AsmWrite(std_regname(Tai_regalloc(hp).reg));
  598. if (hp.next=nil) or
  599. (tai(hp.next).typ<>ait_regalloc) or
  600. (tai_regalloc(hp.next).ratype<>tai_regalloc(hp).ratype) then
  601. break;
  602. hp:=tai(hp.next);
  603. AsmWrite(',');
  604. until false;
  605. AsmWrite(' ');
  606. AsmWriteLn(regallocstr[tai_regalloc(hp).ratype]);
  607. end;
  608. end;
  609. ait_tempalloc :
  610. begin
  611. if (cs_asm_tempalloc in current_settings.globalswitches) then
  612. begin
  613. {$ifdef EXTDEBUG}
  614. if assigned(tai_tempalloc(hp).problem) then
  615. AsmWriteLn(target_asm.comment+'Temp '+tostr(tai_tempalloc(hp).temppos)+','+
  616. tostr(tai_tempalloc(hp).tempsize)+' '+tai_tempalloc(hp).problem^)
  617. else
  618. {$endif EXTDEBUG}
  619. AsmWriteLn(target_asm.comment+'Temp '+tostr(tai_tempalloc(hp).temppos)+','+
  620. tostr(tai_tempalloc(hp).tempsize)+' '+tempallocstr[tai_tempalloc(hp).allocation]);
  621. end;
  622. end;
  623. ait_align :
  624. begin
  625. doalign(tai_align_abstract(hp).aligntype,tai_align_abstract(hp).use_op,tai_align_abstract(hp).fillop,last_align);
  626. end;
  627. ait_section :
  628. begin
  629. if tai_section(hp).sectype<>sec_none then
  630. WriteSection(tai_section(hp).sectype,tai_section(hp).name^,tai_section(hp).secorder)
  631. else
  632. begin
  633. {$ifdef EXTDEBUG}
  634. AsmWrite(target_asm.comment);
  635. AsmWriteln(' sec_none');
  636. {$endif EXTDEBUG}
  637. end;
  638. end;
  639. ait_datablock :
  640. begin
  641. if (target_info.system in systems_darwin) then
  642. begin
  643. { On Mac OS X you can't have common symbols in a shared library
  644. since those are in the TEXT section and the text section is
  645. read-only in shared libraries (so it can be shared among different
  646. processes). The alternate code creates some kind of common symbols
  647. in the data segment.
  648. }
  649. if tai_datablock(hp).is_global then
  650. begin
  651. asmwrite('.globl ');
  652. asmwriteln(tai_datablock(hp).sym.name);
  653. asmwriteln('.data');
  654. asmwrite('.zerofill __DATA, __common, ');
  655. asmwrite(tai_datablock(hp).sym.name);
  656. asmwriteln(', '+tostr(tai_datablock(hp).size)+','+tostr(last_align));
  657. if not(LastSecType in [sec_data,sec_none]) then
  658. writesection(LastSecType,'',secorder_default);
  659. end
  660. else
  661. begin
  662. asmwrite(#9'.lcomm'#9);
  663. asmwrite(tai_datablock(hp).sym.name);
  664. asmwrite(','+tostr(tai_datablock(hp).size));
  665. asmwrite(','+tostr(last_align));
  666. asmln;
  667. end;
  668. end
  669. else
  670. begin
  671. {$ifdef USE_COMM_IN_BSS}
  672. if writingpackages then
  673. begin
  674. { The .comm is required for COMMON symbols. These are used
  675. in the shared library loading. All the symbols declared in
  676. the .so file need to resolve to the data allocated in the main
  677. program (PFV) }
  678. if tai_datablock(hp).is_global then
  679. begin
  680. asmwrite(#9'.comm'#9);
  681. asmwrite(tai_datablock(hp).sym.name);
  682. asmwrite(','+tostr(tai_datablock(hp).size));
  683. asmwrite(','+tostr(last_align));
  684. asmln;
  685. end
  686. else
  687. begin
  688. asmwrite(#9'.lcomm'#9);
  689. asmwrite(tai_datablock(hp).sym.name);
  690. asmwrite(','+tostr(tai_datablock(hp).size));
  691. asmwrite(','+tostr(last_align));
  692. asmln;
  693. end
  694. end
  695. else
  696. {$endif USE_COMM_IN_BSS}
  697. begin
  698. if Tai_datablock(hp).is_global then
  699. begin
  700. asmwrite(#9'.globl ');
  701. asmwriteln(Tai_datablock(hp).sym.name);
  702. end;
  703. if (target_info.system <> system_arm_linux) then
  704. sepChar := '@'
  705. else
  706. sepChar := '%';
  707. if (tf_needs_symbol_type in target_info.flags) then
  708. asmwriteln(#9'.type '+Tai_datablock(hp).sym.name+','+sepChar+'object');
  709. if (tf_needs_symbol_size in target_info.flags) and (tai_datablock(hp).size > 0) then
  710. asmwriteln(#9'.size '+Tai_datablock(hp).sym.name+','+tostr(Tai_datablock(hp).size));
  711. asmwrite(Tai_datablock(hp).sym.name);
  712. asmwriteln(':');
  713. asmwriteln(#9'.zero '+tostr(Tai_datablock(hp).size));
  714. end;
  715. end;
  716. end;
  717. ait_const:
  718. begin
  719. constdef:=tai_const(hp).consttype;
  720. case constdef of
  721. {$ifndef cpu64bitaddr}
  722. aitconst_128bit :
  723. begin
  724. internalerror(200404291);
  725. end;
  726. aitconst_64bit :
  727. begin
  728. if assigned(tai_const(hp).sym) then
  729. internalerror(200404292);
  730. AsmWrite(ait_const2str[aitconst_32bit]);
  731. if target_info.endian = endian_little then
  732. begin
  733. AsmWrite(tostr(longint(lo(tai_const(hp).value))));
  734. AsmWrite(',');
  735. AsmWrite(tostr(longint(hi(tai_const(hp).value))));
  736. end
  737. else
  738. begin
  739. AsmWrite(tostr(longint(hi(tai_const(hp).value))));
  740. AsmWrite(',');
  741. AsmWrite(tostr(longint(lo(tai_const(hp).value))));
  742. end;
  743. AsmLn;
  744. end;
  745. {$endif cpu64bitaddr}
  746. aitconst_uleb128bit,
  747. aitconst_sleb128bit,
  748. {$ifdef cpu64bitaddr}
  749. aitconst_128bit,
  750. aitconst_64bit,
  751. {$endif cpu64bitaddr}
  752. aitconst_32bit,
  753. aitconst_16bit,
  754. aitconst_8bit,
  755. aitconst_rva_symbol,
  756. aitconst_secrel32_symbol,
  757. aitconst_darwin_dwarf_delta32,
  758. aitconst_darwin_dwarf_delta64:
  759. begin
  760. if (target_info.system in systems_darwin) and
  761. (constdef in [aitconst_uleb128bit,aitconst_sleb128bit]) then
  762. begin
  763. AsmWrite(ait_const2str[aitconst_8bit]);
  764. case tai_const(hp).consttype of
  765. aitconst_uleb128bit:
  766. WriteDecodedUleb128(qword(tai_const(hp).value));
  767. aitconst_sleb128bit:
  768. WriteDecodedSleb128(int64(tai_const(hp).value));
  769. end
  770. end
  771. else
  772. begin
  773. AsmWrite(ait_const2str[constdef]);
  774. l:=0;
  775. t := '';
  776. repeat
  777. if assigned(tai_const(hp).sym) then
  778. begin
  779. if assigned(tai_const(hp).endsym) then
  780. begin
  781. if (constdef in [aitconst_darwin_dwarf_delta32,aitconst_darwin_dwarf_delta64]) then
  782. begin
  783. s := NextSetLabel;
  784. t := #9'.set '+s+','+tai_const(hp).endsym.name+'-'+tai_const(hp).sym.name;
  785. end
  786. else
  787. s:=tai_const(hp).endsym.name+'-'+tai_const(hp).sym.name
  788. end
  789. else
  790. s:=tai_const(hp).sym.name;
  791. if tai_const(hp).value<>0 then
  792. s:=s+tostr_with_plus(tai_const(hp).value);
  793. end
  794. else
  795. {$ifdef cpu64bitaddr}
  796. s:=tostr(tai_const(hp).value);
  797. {$else cpu64bitaddr}
  798. { 64 bit constants are already handled above in this case }
  799. s:=tostr(longint(tai_const(hp).value));
  800. {$endif cpu64bitaddr}
  801. AsmWrite(s);
  802. inc(l,length(s));
  803. { Values with symbols are written on a single line to improve
  804. reading of the .s file (PFV) }
  805. if assigned(tai_const(hp).sym) or
  806. not(LastSecType in [sec_data,sec_rodata,sec_rodata_norel]) or
  807. (l>line_length) or
  808. (hp.next=nil) or
  809. (tai(hp.next).typ<>ait_const) or
  810. (tai_const(hp.next).consttype<>constdef) or
  811. assigned(tai_const(hp.next).sym) then
  812. break;
  813. hp:=tai(hp.next);
  814. AsmWrite(',');
  815. until false;
  816. if (t <> '') then
  817. begin
  818. AsmLn;
  819. AsmWrite(t);
  820. end;
  821. end;
  822. AsmLn;
  823. end;
  824. else
  825. internalerror(200704251);
  826. end;
  827. end;
  828. { the "and defined(FPC_HAS_TYPE_EXTENDED)" isn't optimal but currently the only solution
  829. it prevents proper cross compilation to i386 though
  830. }
  831. {$if defined(cpuextended) and defined(FPC_HAS_TYPE_EXTENDED)}
  832. ait_real_80bit :
  833. begin
  834. if do_line then
  835. AsmWriteLn(target_asm.comment+'value: '+extended2str(tai_real_80bit(hp).value));
  836. { Make sure e is a extended type, bestreal could be
  837. a different type (bestreal) !! (PFV) }
  838. e:=tai_real_80bit(hp).value;
  839. AsmWrite(#9'.byte'#9);
  840. for i:=0 to 9 do
  841. begin
  842. if i<>0 then
  843. AsmWrite(',');
  844. AsmWrite(tostr(t80bitarray(e)[i]));
  845. end;
  846. for i:=11 to tai_real_80bit(hp).savesize do
  847. AsmWrite(',0');
  848. AsmLn;
  849. end;
  850. {$endif cpuextended}
  851. ait_real_64bit :
  852. begin
  853. if do_line then
  854. AsmWriteLn(target_asm.comment+'value: '+double2str(tai_real_64bit(hp).value));
  855. d:=tai_real_64bit(hp).value;
  856. { swap the values to correct endian if required }
  857. if source_info.endian <> target_info.endian then
  858. swap64bitarray(t64bitarray(d));
  859. AsmWrite(#9'.byte'#9);
  860. {$ifdef arm}
  861. if tai_real_64bit(hp).formatoptions=fo_hiloswapped then
  862. begin
  863. for i:=4 to 7 do
  864. begin
  865. if i<>4 then
  866. AsmWrite(',');
  867. AsmWrite(tostr(t64bitarray(d)[i]));
  868. end;
  869. for i:=0 to 3 do
  870. begin
  871. AsmWrite(',');
  872. AsmWrite(tostr(t64bitarray(d)[i]));
  873. end;
  874. end
  875. else
  876. {$endif arm}
  877. begin
  878. for i:=0 to 7 do
  879. begin
  880. if i<>0 then
  881. AsmWrite(',');
  882. AsmWrite(tostr(t64bitarray(d)[i]));
  883. end;
  884. end;
  885. AsmLn;
  886. end;
  887. ait_real_32bit :
  888. begin
  889. if do_line then
  890. AsmWriteLn(target_asm.comment+'value: '+single2str(tai_real_32bit(hp).value));
  891. sin:=tai_real_32bit(hp).value;
  892. { swap the values to correct endian if required }
  893. if source_info.endian <> target_info.endian then
  894. swap32bitarray(t32bitarray(sin));
  895. AsmWrite(#9'.byte'#9);
  896. for i:=0 to 3 do
  897. begin
  898. if i<>0 then
  899. AsmWrite(',');
  900. AsmWrite(tostr(t32bitarray(sin)[i]));
  901. end;
  902. AsmLn;
  903. end;
  904. ait_comp_64bit :
  905. begin
  906. if do_line then
  907. AsmWriteLn(target_asm.comment+'value: '+extended2str(tai_comp_64bit(hp).value));
  908. AsmWrite(#9'.byte'#9);
  909. co:=comp(tai_comp_64bit(hp).value);
  910. { swap the values to correct endian if required }
  911. if source_info.endian <> target_info.endian then
  912. swap64bitarray(t64bitarray(co));
  913. for i:=0 to 7 do
  914. begin
  915. if i<>0 then
  916. AsmWrite(',');
  917. AsmWrite(tostr(t64bitarray(co)[i]));
  918. end;
  919. AsmLn;
  920. end;
  921. ait_string :
  922. begin
  923. pos:=0;
  924. for i:=1 to tai_string(hp).len do
  925. begin
  926. if pos=0 then
  927. begin
  928. AsmWrite(#9'.ascii'#9'"');
  929. pos:=20;
  930. end;
  931. ch:=tai_string(hp).str[i-1];
  932. case ch of
  933. #0, {This can't be done by range, because a bug in FPC}
  934. #1..#31,
  935. #128..#255 : s:='\'+tostr(ord(ch) shr 6)+tostr((ord(ch) and 63) shr 3)+tostr(ord(ch) and 7);
  936. '"' : s:='\"';
  937. '\' : s:='\\';
  938. else
  939. s:=ch;
  940. end;
  941. AsmWrite(s);
  942. inc(pos,length(s));
  943. if (pos>line_length) or (i=tai_string(hp).len) then
  944. begin
  945. AsmWriteLn('"');
  946. pos:=0;
  947. end;
  948. end;
  949. end;
  950. ait_label :
  951. begin
  952. if (tai_label(hp).labsym.is_used) then
  953. begin
  954. if (tai_label(hp).labsym.bind=AB_PRIVATE_EXTERN) then
  955. begin
  956. AsmWrite(#9'.private_extern ');
  957. AsmWriteln(tai_label(hp).labsym.name);
  958. end;
  959. if tai_label(hp).labsym.bind in [AB_GLOBAL,AB_PRIVATE_EXTERN] then
  960. begin
  961. AsmWrite('.globl'#9);
  962. AsmWriteLn(tai_label(hp).labsym.name);
  963. end;
  964. AsmWrite(tai_label(hp).labsym.name);
  965. AsmWriteLn(':');
  966. end;
  967. end;
  968. ait_symbol :
  969. begin
  970. if (tai_symbol(hp).sym.bind=AB_PRIVATE_EXTERN) then
  971. begin
  972. AsmWrite(#9'.private_extern ');
  973. AsmWriteln(tai_symbol(hp).sym.name);
  974. end;
  975. if (target_info.system = system_powerpc64_linux) and
  976. (tai_symbol(hp).sym.typ = AT_FUNCTION) and (cs_profile in current_settings.moduleswitches) then
  977. begin
  978. AsmWriteLn('.globl _mcount');
  979. end;
  980. if tai_symbol(hp).is_global then
  981. begin
  982. AsmWrite('.globl'#9);
  983. AsmWriteLn(tai_symbol(hp).sym.name);
  984. end;
  985. if (target_info.system = system_powerpc64_linux) and
  986. (tai_symbol(hp).sym.typ = AT_FUNCTION) then
  987. begin
  988. AsmWriteLn('.section ".opd", "aw"');
  989. AsmWriteLn('.align 3');
  990. AsmWriteLn(tai_symbol(hp).sym.name + ':');
  991. AsmWriteLn('.quad .' + tai_symbol(hp).sym.name + ', .TOC.@tocbase, 0');
  992. AsmWriteLn('.previous');
  993. AsmWriteLn('.size ' + tai_symbol(hp).sym.name + ', 24');
  994. if (tai_symbol(hp).is_global) then
  995. AsmWriteLn('.globl .' + tai_symbol(hp).sym.name);
  996. AsmWriteLn('.type .' + tai_symbol(hp).sym.name + ', @function');
  997. { the dotted name is the name of the actual function entry }
  998. AsmWrite('.');
  999. end
  1000. else
  1001. begin
  1002. if (target_info.system <> system_arm_linux) then
  1003. sepChar := '@'
  1004. else
  1005. sepChar := '#';
  1006. if (tf_needs_symbol_type in target_info.flags) then
  1007. begin
  1008. AsmWrite(#9'.type'#9 + tai_symbol(hp).sym.name);
  1009. if (needsObject(tai_symbol(hp))) then
  1010. AsmWriteLn(',' + sepChar + 'object')
  1011. else
  1012. AsmWriteLn(',' + sepChar + 'function');
  1013. end;
  1014. end;
  1015. if not(tai_symbol(hp).has_value) then
  1016. AsmWriteLn(tai_symbol(hp).sym.name + ':')
  1017. else
  1018. AsmWriteLn(tai_symbol(hp).sym.name + '=' + tostr(tai_symbol(hp).value));
  1019. end;
  1020. {$ifdef arm}
  1021. ait_thumb_func:
  1022. begin
  1023. AsmWriteLn(#9'.thumb_func');
  1024. end;
  1025. {$endif arm}
  1026. ait_symbol_end :
  1027. begin
  1028. if tf_needs_symbol_size in target_info.flags then
  1029. begin
  1030. s:=target_asm.labelprefix+'e'+tostr(symendcount);
  1031. inc(symendcount);
  1032. AsmWriteLn(s+':');
  1033. AsmWrite(#9'.size'#9);
  1034. if (target_info.system = system_powerpc64_linux) and (tai_symbol_end(hp).sym.typ = AT_FUNCTION) then
  1035. AsmWrite('.');
  1036. AsmWrite(tai_symbol_end(hp).sym.name);
  1037. AsmWrite(', '+s+' - ');
  1038. if (target_info.system = system_powerpc64_linux) and (tai_symbol_end(hp).sym.typ = AT_FUNCTION) then
  1039. AsmWrite('.');
  1040. AsmWriteLn(tai_symbol_end(hp).sym.name);
  1041. end;
  1042. end;
  1043. ait_instruction :
  1044. begin
  1045. WriteInstruction(hp);
  1046. end;
  1047. ait_stab :
  1048. begin
  1049. if assigned(tai_stab(hp).str) then
  1050. begin
  1051. AsmWrite(#9'.'+stabtypestr[tai_stab(hp).stabtype]+' ');
  1052. AsmWritePChar(tai_stab(hp).str);
  1053. AsmLn;
  1054. end;
  1055. end;
  1056. ait_force_line,
  1057. ait_function_name : ;
  1058. ait_cutobject :
  1059. begin
  1060. if SmartAsm then
  1061. begin
  1062. { only reset buffer if nothing has changed }
  1063. if AsmSize=AsmStartSize then
  1064. AsmClear
  1065. else
  1066. begin
  1067. AsmClose;
  1068. DoAssemble;
  1069. AsmCreate(tai_cutobject(hp).place);
  1070. end;
  1071. { avoid empty files }
  1072. while assigned(hp.next) and (tai(hp.next).typ in [ait_cutobject,ait_section,ait_comment]) do
  1073. begin
  1074. if tai(hp.next).typ=ait_section then
  1075. LastSecType:=tai_section(hp.next).sectype;
  1076. hp:=tai(hp.next);
  1077. end;
  1078. if LastSecType<>sec_none then
  1079. WriteSection(LastSecType,'',secorder_default);
  1080. AsmStartSize:=AsmSize;
  1081. end;
  1082. end;
  1083. ait_marker :
  1084. if tai_marker(hp).kind=mark_NoLineInfoStart then
  1085. inc(InlineLevel)
  1086. else if tai_marker(hp).kind=mark_NoLineInfoEnd then
  1087. dec(InlineLevel);
  1088. ait_directive :
  1089. begin
  1090. AsmWrite('.'+directivestr[tai_directive(hp).directive]+' ');
  1091. if assigned(tai_directive(hp).name) then
  1092. AsmWrite(tai_directive(hp).name^);
  1093. AsmLn;
  1094. end;
  1095. else
  1096. internalerror(2006012201);
  1097. end;
  1098. hp:=tai(hp.next);
  1099. end;
  1100. end;
  1101. procedure TGNUAssembler.WriteExtraHeader;
  1102. begin
  1103. end;
  1104. procedure TGNUAssembler.WriteInstruction(hp: tai);
  1105. begin
  1106. InstrWriter.WriteInstruction(hp);
  1107. end;
  1108. procedure TGNUAssembler.WriteWeakSymbolDef(s: tasmsymbol);
  1109. begin
  1110. AsmWriteLn(#9'.weak '+s.name);
  1111. end;
  1112. procedure TGNUAssembler.WriteAsmList;
  1113. var
  1114. n : string;
  1115. hal : tasmlisttype;
  1116. i: longint;
  1117. begin
  1118. {$ifdef EXTDEBUG}
  1119. if assigned(current_module.mainsource) then
  1120. Comment(V_Debug,'Start writing gas-styled assembler output for '+current_module.mainsource^);
  1121. {$endif}
  1122. if assigned(current_module.mainsource) then
  1123. n:=ExtractFileName(current_module.mainsource^)
  1124. else
  1125. n:=InputFileName;
  1126. { gcc does not add it either for Darwin (and AIX). Grep for
  1127. TARGET_ASM_FILE_START_FILE_DIRECTIVE in gcc/config/*.h
  1128. }
  1129. if not(target_info.system in systems_darwin) then
  1130. AsmWriteLn(#9'.file "'+FixFileName(n)+'"');
  1131. WriteExtraHeader;
  1132. AsmStartSize:=AsmSize;
  1133. symendcount:=0;
  1134. for hal:=low(TasmlistType) to high(TasmlistType) do
  1135. begin
  1136. AsmWriteLn(target_asm.comment+'Begin asmlist '+AsmlistTypeStr[hal]);
  1137. writetree(current_asmdata.asmlists[hal]);
  1138. AsmWriteLn(target_asm.comment+'End asmlist '+AsmlistTypeStr[hal]);
  1139. end;
  1140. { add weak symbol markers }
  1141. for i:=0 to current_asmdata.asmsymboldict.count-1 do
  1142. if (tasmsymbol(current_asmdata.asmsymboldict[i]).bind=AB_WEAK_EXTERNAL) then
  1143. writeweaksymboldef(tasmsymbol(current_asmdata.asmsymboldict[i]));
  1144. if create_smartlink_sections and
  1145. (target_info.system in systems_darwin) then
  1146. AsmWriteLn(#9'.subsections_via_symbols');
  1147. { "no executable stack" marker for Linux }
  1148. if (target_info.system in systems_linux) and
  1149. not(cs_executable_stack in current_settings.moduleswitches) then
  1150. begin
  1151. AsmWriteLn('.section .note.GNU-stack,"",%progbits');
  1152. end;
  1153. AsmLn;
  1154. {$ifdef EXTDEBUG}
  1155. if assigned(current_module.mainsource) then
  1156. Comment(V_Debug,'Done writing gas-styled assembler output for '+current_module.mainsource^);
  1157. {$endif EXTDEBUG}
  1158. end;
  1159. {****************************************************************************}
  1160. { Apple/GNU Assembler writer }
  1161. {****************************************************************************}
  1162. function TAppleGNUAssembler.sectionname(atype:TAsmSectiontype;const aname:string;aorder:TAsmSectionOrder):string;
  1163. begin
  1164. if (target_info.system in systems_darwin) then
  1165. case atype of
  1166. sec_bss:
  1167. { all bss (lcomm) symbols are automatically put in the right }
  1168. { place by using the lcomm assembler directive }
  1169. atype := sec_none;
  1170. sec_debug_frame,
  1171. sec_eh_frame:
  1172. begin
  1173. result := '.section __DWARF,__debug_info,regular,debug';
  1174. exit;
  1175. end;
  1176. sec_debug_line:
  1177. begin
  1178. result := '.section __DWARF,__debug_line,regular,debug';
  1179. exit;
  1180. end;
  1181. sec_debug_info:
  1182. begin
  1183. result := '.section __DWARF,__debug_info,regular,debug';
  1184. exit;
  1185. end;
  1186. sec_debug_abbrev:
  1187. begin
  1188. result := '.section __DWARF,__debug_abbrev,regular,debug';
  1189. exit;
  1190. end;
  1191. sec_rodata:
  1192. begin
  1193. result := '.const_data';
  1194. exit;
  1195. end;
  1196. sec_rodata_norel:
  1197. begin
  1198. result := '.const';
  1199. exit;
  1200. end;
  1201. sec_fpc:
  1202. begin
  1203. result := '.section __TEXT, .fpc, regular, no_dead_strip';
  1204. exit;
  1205. end;
  1206. sec_code:
  1207. begin
  1208. if (aname='fpc_geteipasebx') or
  1209. (aname='fpc_geteipasecx') then
  1210. begin
  1211. result:='.section __TEXT,__textcoal_nt,coalesced,pure_instructions'#10'.weak_definition '+aname+
  1212. #10'.private_extern '+aname;
  1213. exit;
  1214. end;
  1215. end;
  1216. sec_data_nonlazy:
  1217. begin
  1218. result:='.section __DATA, __nl_symbol_ptr,non_lazy_symbol_pointers';
  1219. exit;
  1220. end;
  1221. sec_data_lazy:
  1222. begin
  1223. result:='.section __DATA, __la_symbol_ptr,lazy_symbol_pointers';
  1224. exit;
  1225. end;
  1226. sec_init_func:
  1227. begin
  1228. result:='.section __DATA, __mod_init_func, mod_init_funcs';
  1229. exit;
  1230. end;
  1231. sec_term_func:
  1232. begin
  1233. result:='.section __DATA, __mod_term_func, mod_term_funcs';
  1234. exit;
  1235. end;
  1236. sec_objc_protocol_ext:
  1237. begin
  1238. result:='.section __OBJC, __protocol_ext, regular, no_dead_strip';
  1239. exit;
  1240. end;
  1241. sec_objc_class_ext:
  1242. begin
  1243. result:='.section __OBJC, __class_ext, regular, no_dead_strip';
  1244. exit;
  1245. end;
  1246. sec_objc_property:
  1247. begin
  1248. result:='.section __OBJC, __property, regular, no_dead_strip';
  1249. exit;
  1250. end;
  1251. sec_objc_image_info:
  1252. begin
  1253. result:='.section __OBJC, __image_info, regular, no_dead_strip';
  1254. exit;
  1255. end;
  1256. sec_objc_cstring_object:
  1257. begin
  1258. result:='.section __OBJC, __cstring_object, regular, no_dead_strip';
  1259. exit;
  1260. end;
  1261. sec_objc_sel_fixup:
  1262. begin
  1263. result:='.section __OBJC, __sel_fixup, regular, no_dead_strip';
  1264. exit;
  1265. end;
  1266. sec_objc_message_refs:
  1267. begin
  1268. if (target_info.system in systems_objc_nfabi) then
  1269. begin
  1270. result:='.section __DATA, __objc_selrefs, literal_pointers, no_dead_strip';
  1271. exit;
  1272. end;
  1273. end;
  1274. sec_objc_cls_refs:
  1275. begin
  1276. if (target_info.system in systems_objc_nfabi) then
  1277. begin
  1278. result:='.section __DATA, __objc_clsrefs, regular, no_dead_strip';
  1279. exit;
  1280. end;
  1281. end;
  1282. sec_objc_meth_var_names,
  1283. sec_objc_class_names:
  1284. begin
  1285. if (target_info.system in systems_objc_nfabi) then
  1286. begin
  1287. result:='.cstring';
  1288. exit
  1289. end;
  1290. end;
  1291. sec_objc_inst_meth,
  1292. sec_objc_cls_meth,
  1293. sec_objc_cat_inst_meth,
  1294. sec_objc_cat_cls_meth:
  1295. begin
  1296. if (target_info.system in systems_objc_nfabi) then
  1297. begin
  1298. result:='.section __DATA, __objc_const';
  1299. exit;
  1300. end;
  1301. end;
  1302. sec_objc_meta_class,
  1303. sec_objc_class:
  1304. begin
  1305. if (target_info.system in systems_objc_nfabi) then
  1306. begin
  1307. result:='.section __DATA, __objc_data';
  1308. exit;
  1309. end;
  1310. end;
  1311. sec_objc_sup_refs:
  1312. begin
  1313. result:='.section __DATA, __objc_superrefs, regular, no_dead_strip';
  1314. exit
  1315. end;
  1316. sec_objc_classlist:
  1317. begin
  1318. result:='.section __DATA, __objc_classlist, regular, no_dead_strip';
  1319. exit
  1320. end;
  1321. sec_objc_nlclasslist:
  1322. begin
  1323. result:='.section __DATA, __objc_nlclasslist, regular, no_dead_strip';
  1324. exit
  1325. end;
  1326. sec_objc_catlist:
  1327. begin
  1328. result:='.section __DATA, __objc_catlist, regular, no_dead_strip';
  1329. exit
  1330. end;
  1331. sec_objc_nlcatlist:
  1332. begin
  1333. result:='.section __DATA, __objc_nlcatlist, regular, no_dead_strip';
  1334. exit
  1335. end;
  1336. sec_objc_protolist:
  1337. begin
  1338. result:='.section __DATA, __objc_protolist, coalesced, no_dead_strip';
  1339. exit;
  1340. end;
  1341. end;
  1342. result := inherited sectionname(atype,aname,aorder);
  1343. end;
  1344. procedure TAppleGNUAssembler.WriteWeakSymbolDef(s: tasmsymbol);
  1345. begin
  1346. AsmWriteLn(#9'.weak_reference '+s.name);
  1347. end;
  1348. {****************************************************************************}
  1349. { a.out/GNU Assembler writer }
  1350. {****************************************************************************}
  1351. function TAoutGNUAssembler.sectionname(atype:TAsmSectiontype;const aname:string;aorder:TAsmSectionOrder):string;
  1352. const
  1353. (* Translation table - replace unsupported section types with basic ones. *)
  1354. SecXTable: array[TAsmSectionType] of TAsmSectionType = (
  1355. sec_none,
  1356. sec_code,
  1357. sec_data,
  1358. sec_data (* sec_rodata *),
  1359. sec_data (* sec_rodata_norel *),
  1360. sec_bss,
  1361. sec_data (* sec_threadvar *),
  1362. { used for wince exception handling }
  1363. sec_code (* sec_pdata *),
  1364. { used for darwin import stubs }
  1365. sec_code (* sec_stub *),
  1366. sec_data,(* sec_data_nonlazy *)
  1367. sec_data,(* sec_data_lazy *)
  1368. sec_data,(* sec_init_func *)
  1369. sec_data,(* sec_term_func *)
  1370. { stabs }
  1371. sec_stab,sec_stabstr,
  1372. { win32 }
  1373. sec_data (* sec_idata2 *),
  1374. sec_data (* sec_idata4 *),
  1375. sec_data (* sec_idata5 *),
  1376. sec_data (* sec_idata6 *),
  1377. sec_data (* sec_idata7 *),
  1378. sec_data (* sec_edata *),
  1379. { C++ exception handling unwinding (uses dwarf) }
  1380. sec_eh_frame,
  1381. { dwarf }
  1382. sec_debug_frame,
  1383. sec_debug_info,
  1384. sec_debug_line,
  1385. sec_debug_abbrev,
  1386. { ELF resources (+ references to stabs debug information sections) }
  1387. sec_code (* sec_fpc *),
  1388. { Table of contents section }
  1389. sec_code (* sec_toc *),
  1390. sec_code (* sec_init *),
  1391. sec_code (* sec_fini *),
  1392. sec_none (* sec_objc_class *),
  1393. sec_none (* sec_objc_meta_class *),
  1394. sec_none (* sec_objc_cat_cls_meth *),
  1395. sec_none (* sec_objc_cat_inst_meth *),
  1396. sec_none (* sec_objc_protocol *),
  1397. sec_none (* sec_objc_string_object *),
  1398. sec_none (* sec_objc_cls_meth *),
  1399. sec_none (* sec_objc_inst_meth *),
  1400. sec_none (* sec_objc_cls_refs *),
  1401. sec_none (* sec_objc_message_refs *),
  1402. sec_none (* sec_objc_symbols *),
  1403. sec_none (* sec_objc_category *),
  1404. sec_none (* sec_objc_class_vars *),
  1405. sec_none (* sec_objc_instance_vars *),
  1406. sec_none (* sec_objc_module_info *),
  1407. sec_none (* sec_objc_class_names *),
  1408. sec_none (* sec_objc_meth_var_types *),
  1409. sec_none (* sec_objc_meth_var_names *),
  1410. sec_none (* sec_objc_selector_strs *),
  1411. sec_none (* sec_objc_protocol_ext *),
  1412. sec_none (* sec_objc_class_ext *),
  1413. sec_none (* sec_objc_property *),
  1414. sec_none (* sec_objc_image_info *),
  1415. sec_none (* sec_objc_cstring_object *),
  1416. sec_none (* sec_objc_sel_fixup *),
  1417. sec_none (* sec_objc_data *),
  1418. sec_none (* sec_objc_const *),
  1419. sec_none (* sec_objc_sup_refs *),
  1420. sec_none (* sec_data_coalesced *),
  1421. sec_none (* sec_objc_classlist *),
  1422. sec_none (* sec_objc_nlclasslist *),
  1423. sec_none (* sec_objc_catlist *),
  1424. sec_none (* sec_objc_nlcatlist *),
  1425. sec_none (* sec_objc_protlist *)
  1426. );
  1427. begin
  1428. Result := inherited SectionName (SecXTable [AType], AName, AOrder);
  1429. end;
  1430. {****************************************************************************}
  1431. { Abstract Instruction Writer }
  1432. {****************************************************************************}
  1433. constructor TCPUInstrWriter.create(_owner: TGNUAssembler);
  1434. begin
  1435. inherited create;
  1436. owner := _owner;
  1437. end;
  1438. end.