aggas.pas 52 KB

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