aggas.pas 54 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562
  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. { section type user gives the user full controll on the section name }
  359. if atype=sec_user then
  360. secname:=aname;
  361. { For bss we need to set some flags that are target dependent,
  362. it is easier to disable it for smartlinking. It doesn't take up
  363. filespace }
  364. if not(target_info.system in systems_darwin) and
  365. create_smartlink_sections and
  366. (aname<>'') and
  367. (atype<>sec_toc) and
  368. (atype<>sec_user) and
  369. { on embedded systems every byte counts, so smartlink bss too }
  370. ((atype<>sec_bss) or (target_info.system in systems_embedded)) then
  371. begin
  372. case aorder of
  373. secorder_begin :
  374. sep:='.b_';
  375. secorder_end :
  376. sep:='.z_';
  377. else
  378. sep:='.n_';
  379. end;
  380. result:=secname+sep+aname
  381. end
  382. else
  383. result:=secname;
  384. end;
  385. procedure TGNUAssembler.WriteSection(atype:TAsmSectiontype;const aname:string;aorder:TAsmSectionOrder);
  386. var
  387. s : string;
  388. begin
  389. AsmLn;
  390. case target_info.system of
  391. system_i386_OS2,
  392. system_i386_EMX,
  393. system_m68k_amiga, { amiga has old GNU AS (2.14), which blews up from .section (KB) }
  394. system_m68k_linux: ;
  395. system_powerpc_darwin,
  396. system_i386_darwin,
  397. system_i386_iphonesim,
  398. system_powerpc64_darwin,
  399. system_x86_64_darwin,
  400. system_arm_darwin:
  401. begin
  402. if (atype in [sec_stub,sec_objc_data,sec_objc_const,sec_data_coalesced]) then
  403. AsmWrite('.section ');
  404. end
  405. else
  406. AsmWrite('.section ');
  407. end;
  408. s:=sectionname(atype,aname,aorder);
  409. AsmWrite(s);
  410. case atype of
  411. sec_fpc :
  412. if aname = 'resptrs' then
  413. AsmWrite(', "a", @progbits');
  414. sec_stub :
  415. begin
  416. case target_info.system of
  417. { there are processor-independent shortcuts available }
  418. { for this, namely .symbol_stub and .picsymbol_stub, but }
  419. { they don't work and gcc doesn't use them either... }
  420. system_powerpc_darwin,
  421. system_powerpc64_darwin:
  422. if (cs_create_pic in current_settings.moduleswitches) then
  423. AsmWriteln('__TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32')
  424. else
  425. AsmWriteln('__TEXT,__symbol_stub1,symbol_stubs,pure_instructions,16');
  426. system_i386_darwin,
  427. system_i386_iphonesim:
  428. AsmWriteln('__IMPORT,__jump_table,symbol_stubs,self_modifying_code+pure_instructions,5');
  429. system_arm_darwin:
  430. if (cs_create_pic in current_settings.moduleswitches) then
  431. AsmWriteln('.section __TEXT,__picsymbolstub4,symbol_stubs,none,16')
  432. else
  433. AsmWriteln('.section __TEXT,__symbol_stub4,symbol_stubs,none,12')
  434. { darwin/x86-64 uses RIP-based GOT addressing, no symbol stubs }
  435. else
  436. internalerror(2006031101);
  437. end;
  438. end;
  439. end;
  440. AsmLn;
  441. LastSecType:=atype;
  442. end;
  443. procedure TGNUAssembler.WriteDecodedUleb128(a: qword);
  444. var
  445. i,len : longint;
  446. buf : array[0..63] of byte;
  447. begin
  448. len:=EncodeUleb128(a,buf);
  449. for i:=0 to len-1 do
  450. begin
  451. if (i > 0) then
  452. AsmWrite(',');
  453. AsmWrite(tostr(buf[i]));
  454. end;
  455. end;
  456. procedure TGNUAssembler.WriteDecodedSleb128(a: int64);
  457. var
  458. i,len : longint;
  459. buf : array[0..255] of byte;
  460. begin
  461. len:=EncodeSleb128(a,buf);
  462. for i:=0 to len-1 do
  463. begin
  464. if (i > 0) then
  465. AsmWrite(',');
  466. AsmWrite(tostr(buf[i]));
  467. end;
  468. end;
  469. procedure TGNUAssembler.WriteTree(p:TAsmList);
  470. function needsObject(hp : tai_symbol) : boolean;
  471. begin
  472. needsObject :=
  473. (
  474. assigned(hp.next) and
  475. (tai(hp.next).typ in [ait_const,ait_datablock,
  476. ait_real_32bit,ait_real_64bit,ait_real_80bit,ait_comp_64bit])
  477. ) or
  478. (hp.sym.typ=AT_DATA);
  479. end;
  480. procedure doalign(alignment: byte; use_op: boolean; fillop: byte; out last_align: longint);
  481. var
  482. i: longint;
  483. begin
  484. last_align:=alignment;
  485. if alignment>1 then
  486. begin
  487. if not(target_info.system in systems_darwin) then
  488. begin
  489. AsmWrite(#9'.balign '+tostr(alignment));
  490. if use_op then
  491. AsmWrite(','+tostr(fillop))
  492. {$ifdef x86}
  493. { force NOP as alignment op code }
  494. else if LastSecType=sec_code then
  495. AsmWrite(',0x90');
  496. {$endif x86}
  497. end
  498. else
  499. begin
  500. { darwin as only supports .align }
  501. if not ispowerof2(alignment,i) then
  502. internalerror(2003010305);
  503. AsmWrite(#9'.align '+tostr(i));
  504. last_align:=i;
  505. end;
  506. AsmLn;
  507. end;
  508. end;
  509. var
  510. ch : char;
  511. hp : tai;
  512. hp1 : tailineinfo;
  513. constdef : taiconst_type;
  514. s,t : string;
  515. i,pos,l : longint;
  516. InlineLevel : longint;
  517. last_align : longint;
  518. co : comp;
  519. sin : single;
  520. d : double;
  521. {$ifdef cpuextended}
  522. e : extended;
  523. {$endif cpuextended}
  524. do_line : boolean;
  525. sepChar : char;
  526. begin
  527. if not assigned(p) then
  528. exit;
  529. last_align := 2;
  530. InlineLevel:=0;
  531. { lineinfo is only needed for al_procedures (PFV) }
  532. do_line:=(cs_asm_source in current_settings.globalswitches) or
  533. ((cs_lineinfo in current_settings.moduleswitches)
  534. and (p=current_asmdata.asmlists[al_procedures]));
  535. hp:=tai(p.first);
  536. while assigned(hp) do
  537. begin
  538. prefetch(pointer(hp.next)^);
  539. if not(hp.typ in SkipLineInfo) then
  540. begin
  541. hp1 := hp as tailineinfo;
  542. current_filepos:=hp1.fileinfo;
  543. { no line info for inlined code }
  544. if do_line and (inlinelevel=0) then
  545. begin
  546. { load infile }
  547. if lastfileinfo.fileindex<>hp1.fileinfo.fileindex then
  548. begin
  549. infile:=current_module.sourcefiles.get_file(hp1.fileinfo.fileindex);
  550. if assigned(infile) then
  551. begin
  552. { open only if needed !! }
  553. if (cs_asm_source in current_settings.globalswitches) then
  554. infile.open;
  555. end;
  556. { avoid unnecessary reopens of the same file !! }
  557. lastfileinfo.fileindex:=hp1.fileinfo.fileindex;
  558. { be sure to change line !! }
  559. lastfileinfo.line:=-1;
  560. end;
  561. { write source }
  562. if (cs_asm_source in current_settings.globalswitches) and
  563. assigned(infile) then
  564. begin
  565. if (infile<>lastinfile) then
  566. begin
  567. AsmWriteLn(target_asm.comment+'['+infile.name^+']');
  568. if assigned(lastinfile) then
  569. lastinfile.close;
  570. end;
  571. if (hp1.fileinfo.line<>lastfileinfo.line) and
  572. ((hp1.fileinfo.line<infile.maxlinebuf) or (InlineLevel>0)) then
  573. begin
  574. if (hp1.fileinfo.line<>0) and
  575. ((infile.linebuf^[hp1.fileinfo.line]>=0) or (InlineLevel>0)) then
  576. AsmWriteLn(target_asm.comment+'['+tostr(hp1.fileinfo.line)+'] '+
  577. fixline(infile.GetLineStr(hp1.fileinfo.line)));
  578. { set it to a negative value !
  579. to make that is has been read already !! PM }
  580. if (infile.linebuf^[hp1.fileinfo.line]>=0) then
  581. infile.linebuf^[hp1.fileinfo.line]:=-infile.linebuf^[hp1.fileinfo.line]-1;
  582. end;
  583. end;
  584. lastfileinfo:=hp1.fileinfo;
  585. lastinfile:=infile;
  586. end;
  587. end;
  588. case hp.typ of
  589. ait_comment :
  590. Begin
  591. AsmWrite(target_asm.comment);
  592. AsmWritePChar(tai_comment(hp).str);
  593. AsmLn;
  594. End;
  595. ait_regalloc :
  596. begin
  597. if (cs_asm_regalloc in current_settings.globalswitches) then
  598. begin
  599. AsmWrite(#9+target_asm.comment+'Register ');
  600. repeat
  601. AsmWrite(std_regname(Tai_regalloc(hp).reg));
  602. if (hp.next=nil) or
  603. (tai(hp.next).typ<>ait_regalloc) or
  604. (tai_regalloc(hp.next).ratype<>tai_regalloc(hp).ratype) then
  605. break;
  606. hp:=tai(hp.next);
  607. AsmWrite(',');
  608. until false;
  609. AsmWrite(' ');
  610. AsmWriteLn(regallocstr[tai_regalloc(hp).ratype]);
  611. end;
  612. end;
  613. ait_tempalloc :
  614. begin
  615. if (cs_asm_tempalloc in current_settings.globalswitches) then
  616. begin
  617. {$ifdef EXTDEBUG}
  618. if assigned(tai_tempalloc(hp).problem) then
  619. AsmWriteLn(target_asm.comment+'Temp '+tostr(tai_tempalloc(hp).temppos)+','+
  620. tostr(tai_tempalloc(hp).tempsize)+' '+tai_tempalloc(hp).problem^)
  621. else
  622. {$endif EXTDEBUG}
  623. AsmWriteLn(target_asm.comment+'Temp '+tostr(tai_tempalloc(hp).temppos)+','+
  624. tostr(tai_tempalloc(hp).tempsize)+' '+tempallocstr[tai_tempalloc(hp).allocation]);
  625. end;
  626. end;
  627. ait_align :
  628. begin
  629. doalign(tai_align_abstract(hp).aligntype,tai_align_abstract(hp).use_op,tai_align_abstract(hp).fillop,last_align);
  630. end;
  631. ait_section :
  632. begin
  633. if tai_section(hp).sectype<>sec_none then
  634. WriteSection(tai_section(hp).sectype,tai_section(hp).name^,tai_section(hp).secorder)
  635. else
  636. begin
  637. {$ifdef EXTDEBUG}
  638. AsmWrite(target_asm.comment);
  639. AsmWriteln(' sec_none');
  640. {$endif EXTDEBUG}
  641. end;
  642. end;
  643. ait_datablock :
  644. begin
  645. if (target_info.system in systems_darwin) then
  646. begin
  647. { On Mac OS X you can't have common symbols in a shared library
  648. since those are in the TEXT section and the text section is
  649. read-only in shared libraries (so it can be shared among different
  650. processes). The alternate code creates some kind of common symbols
  651. in the data segment.
  652. }
  653. if tai_datablock(hp).is_global then
  654. begin
  655. asmwrite('.globl ');
  656. asmwriteln(tai_datablock(hp).sym.name);
  657. asmwriteln('.data');
  658. asmwrite('.zerofill __DATA, __common, ');
  659. asmwrite(tai_datablock(hp).sym.name);
  660. asmwriteln(', '+tostr(tai_datablock(hp).size)+','+tostr(last_align));
  661. if not(LastSecType in [sec_data,sec_none]) then
  662. writesection(LastSecType,'',secorder_default);
  663. end
  664. else
  665. begin
  666. asmwrite(#9'.lcomm'#9);
  667. asmwrite(tai_datablock(hp).sym.name);
  668. asmwrite(','+tostr(tai_datablock(hp).size));
  669. asmwrite(','+tostr(last_align));
  670. asmln;
  671. end;
  672. end
  673. else
  674. begin
  675. {$ifdef USE_COMM_IN_BSS}
  676. if writingpackages then
  677. begin
  678. { The .comm is required for COMMON symbols. These are used
  679. in the shared library loading. All the symbols declared in
  680. the .so file need to resolve to the data allocated in the main
  681. program (PFV) }
  682. if tai_datablock(hp).is_global then
  683. begin
  684. asmwrite(#9'.comm'#9);
  685. asmwrite(tai_datablock(hp).sym.name);
  686. asmwrite(','+tostr(tai_datablock(hp).size));
  687. asmwrite(','+tostr(last_align));
  688. asmln;
  689. end
  690. else
  691. begin
  692. asmwrite(#9'.lcomm'#9);
  693. asmwrite(tai_datablock(hp).sym.name);
  694. asmwrite(','+tostr(tai_datablock(hp).size));
  695. asmwrite(','+tostr(last_align));
  696. asmln;
  697. end
  698. end
  699. else
  700. {$endif USE_COMM_IN_BSS}
  701. begin
  702. if Tai_datablock(hp).is_global then
  703. begin
  704. asmwrite(#9'.globl ');
  705. asmwriteln(Tai_datablock(hp).sym.name);
  706. end;
  707. if (target_info.system <> system_arm_linux) then
  708. sepChar := '@'
  709. else
  710. sepChar := '%';
  711. if (tf_needs_symbol_type in target_info.flags) then
  712. asmwriteln(#9'.type '+Tai_datablock(hp).sym.name+','+sepChar+'object');
  713. if (tf_needs_symbol_size in target_info.flags) and (tai_datablock(hp).size > 0) then
  714. asmwriteln(#9'.size '+Tai_datablock(hp).sym.name+','+tostr(Tai_datablock(hp).size));
  715. asmwrite(Tai_datablock(hp).sym.name);
  716. asmwriteln(':');
  717. asmwriteln(#9'.zero '+tostr(Tai_datablock(hp).size));
  718. end;
  719. end;
  720. end;
  721. ait_const:
  722. begin
  723. constdef:=tai_const(hp).consttype;
  724. case constdef of
  725. {$ifndef cpu64bitaddr}
  726. aitconst_128bit :
  727. begin
  728. internalerror(200404291);
  729. end;
  730. aitconst_64bit :
  731. begin
  732. if assigned(tai_const(hp).sym) then
  733. internalerror(200404292);
  734. AsmWrite(ait_const2str[aitconst_32bit]);
  735. if target_info.endian = endian_little then
  736. begin
  737. AsmWrite(tostr(longint(lo(tai_const(hp).value))));
  738. AsmWrite(',');
  739. AsmWrite(tostr(longint(hi(tai_const(hp).value))));
  740. end
  741. else
  742. begin
  743. AsmWrite(tostr(longint(hi(tai_const(hp).value))));
  744. AsmWrite(',');
  745. AsmWrite(tostr(longint(lo(tai_const(hp).value))));
  746. end;
  747. AsmLn;
  748. end;
  749. {$endif cpu64bitaddr}
  750. aitconst_uleb128bit,
  751. aitconst_sleb128bit,
  752. {$ifdef cpu64bitaddr}
  753. aitconst_128bit,
  754. aitconst_64bit,
  755. {$endif cpu64bitaddr}
  756. aitconst_32bit,
  757. aitconst_16bit,
  758. aitconst_8bit,
  759. aitconst_rva_symbol,
  760. aitconst_secrel32_symbol,
  761. aitconst_darwin_dwarf_delta32,
  762. aitconst_darwin_dwarf_delta64:
  763. begin
  764. if (target_info.system in systems_darwin) and
  765. (constdef in [aitconst_uleb128bit,aitconst_sleb128bit]) then
  766. begin
  767. AsmWrite(ait_const2str[aitconst_8bit]);
  768. case tai_const(hp).consttype of
  769. aitconst_uleb128bit:
  770. WriteDecodedUleb128(qword(tai_const(hp).value));
  771. aitconst_sleb128bit:
  772. WriteDecodedSleb128(int64(tai_const(hp).value));
  773. end
  774. end
  775. else
  776. begin
  777. AsmWrite(ait_const2str[constdef]);
  778. l:=0;
  779. t := '';
  780. repeat
  781. if assigned(tai_const(hp).sym) then
  782. begin
  783. if assigned(tai_const(hp).endsym) then
  784. begin
  785. if (constdef in [aitconst_darwin_dwarf_delta32,aitconst_darwin_dwarf_delta64]) then
  786. begin
  787. s := NextSetLabel;
  788. t := #9'.set '+s+','+tai_const(hp).endsym.name+'-'+tai_const(hp).sym.name;
  789. end
  790. else
  791. s:=tai_const(hp).endsym.name+'-'+tai_const(hp).sym.name
  792. end
  793. else
  794. s:=tai_const(hp).sym.name;
  795. if tai_const(hp).value<>0 then
  796. s:=s+tostr_with_plus(tai_const(hp).value);
  797. end
  798. else
  799. {$ifdef cpu64bitaddr}
  800. s:=tostr(tai_const(hp).value);
  801. {$else cpu64bitaddr}
  802. { 64 bit constants are already handled above in this case }
  803. s:=tostr(longint(tai_const(hp).value));
  804. {$endif cpu64bitaddr}
  805. AsmWrite(s);
  806. inc(l,length(s));
  807. { Values with symbols are written on a single line to improve
  808. reading of the .s file (PFV) }
  809. if assigned(tai_const(hp).sym) or
  810. not(LastSecType in [sec_data,sec_rodata,sec_rodata_norel]) or
  811. (l>line_length) or
  812. (hp.next=nil) or
  813. (tai(hp.next).typ<>ait_const) or
  814. (tai_const(hp.next).consttype<>constdef) or
  815. assigned(tai_const(hp.next).sym) then
  816. break;
  817. hp:=tai(hp.next);
  818. AsmWrite(',');
  819. until false;
  820. if (t <> '') then
  821. begin
  822. AsmLn;
  823. AsmWrite(t);
  824. end;
  825. end;
  826. AsmLn;
  827. end;
  828. else
  829. internalerror(200704251);
  830. end;
  831. end;
  832. { the "and defined(FPC_HAS_TYPE_EXTENDED)" isn't optimal but currently the only solution
  833. it prevents proper cross compilation to i386 though
  834. }
  835. {$if defined(cpuextended) and defined(FPC_HAS_TYPE_EXTENDED)}
  836. ait_real_80bit :
  837. begin
  838. if do_line then
  839. AsmWriteLn(target_asm.comment+'value: '+extended2str(tai_real_80bit(hp).value));
  840. { Make sure e is a extended type, bestreal could be
  841. a different type (bestreal) !! (PFV) }
  842. e:=tai_real_80bit(hp).value;
  843. AsmWrite(#9'.byte'#9);
  844. for i:=0 to 9 do
  845. begin
  846. if i<>0 then
  847. AsmWrite(',');
  848. AsmWrite(tostr(t80bitarray(e)[i]));
  849. end;
  850. for i:=11 to tai_real_80bit(hp).savesize do
  851. AsmWrite(',0');
  852. AsmLn;
  853. end;
  854. {$endif cpuextended}
  855. ait_real_64bit :
  856. begin
  857. if do_line then
  858. AsmWriteLn(target_asm.comment+'value: '+double2str(tai_real_64bit(hp).value));
  859. d:=tai_real_64bit(hp).value;
  860. { swap the values to correct endian if required }
  861. if source_info.endian <> target_info.endian then
  862. swap64bitarray(t64bitarray(d));
  863. AsmWrite(#9'.byte'#9);
  864. {$ifdef arm}
  865. if tai_real_64bit(hp).formatoptions=fo_hiloswapped then
  866. begin
  867. for i:=4 to 7 do
  868. begin
  869. if i<>4 then
  870. AsmWrite(',');
  871. AsmWrite(tostr(t64bitarray(d)[i]));
  872. end;
  873. for i:=0 to 3 do
  874. begin
  875. AsmWrite(',');
  876. AsmWrite(tostr(t64bitarray(d)[i]));
  877. end;
  878. end
  879. else
  880. {$endif arm}
  881. begin
  882. for i:=0 to 7 do
  883. begin
  884. if i<>0 then
  885. AsmWrite(',');
  886. AsmWrite(tostr(t64bitarray(d)[i]));
  887. end;
  888. end;
  889. AsmLn;
  890. end;
  891. ait_real_32bit :
  892. begin
  893. if do_line then
  894. AsmWriteLn(target_asm.comment+'value: '+single2str(tai_real_32bit(hp).value));
  895. sin:=tai_real_32bit(hp).value;
  896. { swap the values to correct endian if required }
  897. if source_info.endian <> target_info.endian then
  898. swap32bitarray(t32bitarray(sin));
  899. AsmWrite(#9'.byte'#9);
  900. for i:=0 to 3 do
  901. begin
  902. if i<>0 then
  903. AsmWrite(',');
  904. AsmWrite(tostr(t32bitarray(sin)[i]));
  905. end;
  906. AsmLn;
  907. end;
  908. ait_comp_64bit :
  909. begin
  910. if do_line then
  911. AsmWriteLn(target_asm.comment+'value: '+extended2str(tai_comp_64bit(hp).value));
  912. AsmWrite(#9'.byte'#9);
  913. co:=comp(tai_comp_64bit(hp).value);
  914. { swap the values to correct endian if required }
  915. if source_info.endian <> target_info.endian then
  916. swap64bitarray(t64bitarray(co));
  917. for i:=0 to 7 do
  918. begin
  919. if i<>0 then
  920. AsmWrite(',');
  921. AsmWrite(tostr(t64bitarray(co)[i]));
  922. end;
  923. AsmLn;
  924. end;
  925. ait_string :
  926. begin
  927. pos:=0;
  928. for i:=1 to tai_string(hp).len do
  929. begin
  930. if pos=0 then
  931. begin
  932. AsmWrite(#9'.ascii'#9'"');
  933. pos:=20;
  934. end;
  935. ch:=tai_string(hp).str[i-1];
  936. case ch of
  937. #0, {This can't be done by range, because a bug in FPC}
  938. #1..#31,
  939. #128..#255 : s:='\'+tostr(ord(ch) shr 6)+tostr((ord(ch) and 63) shr 3)+tostr(ord(ch) and 7);
  940. '"' : s:='\"';
  941. '\' : s:='\\';
  942. else
  943. s:=ch;
  944. end;
  945. AsmWrite(s);
  946. inc(pos,length(s));
  947. if (pos>line_length) or (i=tai_string(hp).len) then
  948. begin
  949. AsmWriteLn('"');
  950. pos:=0;
  951. end;
  952. end;
  953. end;
  954. ait_label :
  955. begin
  956. if (tai_label(hp).labsym.is_used) then
  957. begin
  958. if (tai_label(hp).labsym.bind=AB_PRIVATE_EXTERN) then
  959. begin
  960. AsmWrite(#9'.private_extern ');
  961. AsmWriteln(tai_label(hp).labsym.name);
  962. end;
  963. if tai_label(hp).labsym.bind in [AB_GLOBAL,AB_PRIVATE_EXTERN] then
  964. begin
  965. AsmWrite('.globl'#9);
  966. AsmWriteLn(tai_label(hp).labsym.name);
  967. end;
  968. AsmWrite(tai_label(hp).labsym.name);
  969. AsmWriteLn(':');
  970. end;
  971. end;
  972. ait_symbol :
  973. begin
  974. if (tai_symbol(hp).sym.bind=AB_PRIVATE_EXTERN) then
  975. begin
  976. AsmWrite(#9'.private_extern ');
  977. AsmWriteln(tai_symbol(hp).sym.name);
  978. end;
  979. if (target_info.system = system_powerpc64_linux) and
  980. (tai_symbol(hp).sym.typ = AT_FUNCTION) and (cs_profile in current_settings.moduleswitches) then
  981. begin
  982. AsmWriteLn('.globl _mcount');
  983. end;
  984. if tai_symbol(hp).is_global then
  985. begin
  986. AsmWrite('.globl'#9);
  987. AsmWriteLn(tai_symbol(hp).sym.name);
  988. end;
  989. if (target_info.system = system_powerpc64_linux) and
  990. (tai_symbol(hp).sym.typ = AT_FUNCTION) then
  991. begin
  992. AsmWriteLn('.section ".opd", "aw"');
  993. AsmWriteLn('.align 3');
  994. AsmWriteLn(tai_symbol(hp).sym.name + ':');
  995. AsmWriteLn('.quad .' + tai_symbol(hp).sym.name + ', .TOC.@tocbase, 0');
  996. AsmWriteLn('.previous');
  997. AsmWriteLn('.size ' + tai_symbol(hp).sym.name + ', 24');
  998. if (tai_symbol(hp).is_global) then
  999. AsmWriteLn('.globl .' + tai_symbol(hp).sym.name);
  1000. AsmWriteLn('.type .' + tai_symbol(hp).sym.name + ', @function');
  1001. { the dotted name is the name of the actual function entry }
  1002. AsmWrite('.');
  1003. end
  1004. else
  1005. begin
  1006. if (target_info.system <> system_arm_linux) then
  1007. sepChar := '@'
  1008. else
  1009. sepChar := '#';
  1010. if (tf_needs_symbol_type in target_info.flags) then
  1011. begin
  1012. AsmWrite(#9'.type'#9 + tai_symbol(hp).sym.name);
  1013. if (needsObject(tai_symbol(hp))) then
  1014. AsmWriteLn(',' + sepChar + 'object')
  1015. else
  1016. AsmWriteLn(',' + sepChar + 'function');
  1017. end;
  1018. end;
  1019. if not(tai_symbol(hp).has_value) then
  1020. AsmWriteLn(tai_symbol(hp).sym.name + ':')
  1021. else
  1022. AsmWriteLn(tai_symbol(hp).sym.name + '=' + tostr(tai_symbol(hp).value));
  1023. end;
  1024. {$ifdef arm}
  1025. ait_thumb_func:
  1026. begin
  1027. AsmWriteLn(#9'.thumb_func');
  1028. end;
  1029. {$endif arm}
  1030. ait_symbol_end :
  1031. begin
  1032. if tf_needs_symbol_size in target_info.flags then
  1033. begin
  1034. s:=target_asm.labelprefix+'e'+tostr(symendcount);
  1035. inc(symendcount);
  1036. AsmWriteLn(s+':');
  1037. AsmWrite(#9'.size'#9);
  1038. if (target_info.system = system_powerpc64_linux) and (tai_symbol_end(hp).sym.typ = AT_FUNCTION) then
  1039. AsmWrite('.');
  1040. AsmWrite(tai_symbol_end(hp).sym.name);
  1041. AsmWrite(', '+s+' - ');
  1042. if (target_info.system = system_powerpc64_linux) and (tai_symbol_end(hp).sym.typ = AT_FUNCTION) then
  1043. AsmWrite('.');
  1044. AsmWriteLn(tai_symbol_end(hp).sym.name);
  1045. end;
  1046. end;
  1047. ait_instruction :
  1048. begin
  1049. WriteInstruction(hp);
  1050. end;
  1051. ait_stab :
  1052. begin
  1053. if assigned(tai_stab(hp).str) then
  1054. begin
  1055. AsmWrite(#9'.'+stabtypestr[tai_stab(hp).stabtype]+' ');
  1056. AsmWritePChar(tai_stab(hp).str);
  1057. AsmLn;
  1058. end;
  1059. end;
  1060. ait_force_line,
  1061. ait_function_name : ;
  1062. ait_cutobject :
  1063. begin
  1064. if SmartAsm then
  1065. begin
  1066. { only reset buffer if nothing has changed }
  1067. if AsmSize=AsmStartSize then
  1068. AsmClear
  1069. else
  1070. begin
  1071. AsmClose;
  1072. DoAssemble;
  1073. AsmCreate(tai_cutobject(hp).place);
  1074. end;
  1075. { avoid empty files }
  1076. while assigned(hp.next) and (tai(hp.next).typ in [ait_cutobject,ait_section,ait_comment]) do
  1077. begin
  1078. if tai(hp.next).typ=ait_section then
  1079. LastSecType:=tai_section(hp.next).sectype;
  1080. hp:=tai(hp.next);
  1081. end;
  1082. if LastSecType<>sec_none then
  1083. WriteSection(LastSecType,'',secorder_default);
  1084. AsmStartSize:=AsmSize;
  1085. end;
  1086. end;
  1087. ait_marker :
  1088. if tai_marker(hp).kind=mark_NoLineInfoStart then
  1089. inc(InlineLevel)
  1090. else if tai_marker(hp).kind=mark_NoLineInfoEnd then
  1091. dec(InlineLevel);
  1092. ait_directive :
  1093. begin
  1094. AsmWrite('.'+directivestr[tai_directive(hp).directive]+' ');
  1095. if assigned(tai_directive(hp).name) then
  1096. AsmWrite(tai_directive(hp).name^);
  1097. AsmLn;
  1098. end;
  1099. else
  1100. internalerror(2006012201);
  1101. end;
  1102. hp:=tai(hp.next);
  1103. end;
  1104. end;
  1105. procedure TGNUAssembler.WriteExtraHeader;
  1106. begin
  1107. end;
  1108. procedure TGNUAssembler.WriteInstruction(hp: tai);
  1109. begin
  1110. InstrWriter.WriteInstruction(hp);
  1111. end;
  1112. procedure TGNUAssembler.WriteWeakSymbolDef(s: tasmsymbol);
  1113. begin
  1114. AsmWriteLn(#9'.weak '+s.name);
  1115. end;
  1116. procedure TGNUAssembler.WriteAsmList;
  1117. var
  1118. n : string;
  1119. hal : tasmlisttype;
  1120. i: longint;
  1121. begin
  1122. {$ifdef EXTDEBUG}
  1123. if assigned(current_module.mainsource) then
  1124. Comment(V_Debug,'Start writing gas-styled assembler output for '+current_module.mainsource^);
  1125. {$endif}
  1126. if assigned(current_module.mainsource) then
  1127. n:=ExtractFileName(current_module.mainsource^)
  1128. else
  1129. n:=InputFileName;
  1130. { gcc does not add it either for Darwin (and AIX). Grep for
  1131. TARGET_ASM_FILE_START_FILE_DIRECTIVE in gcc/config/*.h
  1132. }
  1133. if not(target_info.system in systems_darwin) then
  1134. AsmWriteLn(#9'.file "'+FixFileName(n)+'"');
  1135. WriteExtraHeader;
  1136. AsmStartSize:=AsmSize;
  1137. symendcount:=0;
  1138. for hal:=low(TasmlistType) to high(TasmlistType) do
  1139. begin
  1140. AsmWriteLn(target_asm.comment+'Begin asmlist '+AsmlistTypeStr[hal]);
  1141. writetree(current_asmdata.asmlists[hal]);
  1142. AsmWriteLn(target_asm.comment+'End asmlist '+AsmlistTypeStr[hal]);
  1143. end;
  1144. { add weak symbol markers }
  1145. for i:=0 to current_asmdata.asmsymboldict.count-1 do
  1146. if (tasmsymbol(current_asmdata.asmsymboldict[i]).bind=AB_WEAK_EXTERNAL) then
  1147. writeweaksymboldef(tasmsymbol(current_asmdata.asmsymboldict[i]));
  1148. if create_smartlink_sections and
  1149. (target_info.system in systems_darwin) then
  1150. AsmWriteLn(#9'.subsections_via_symbols');
  1151. { "no executable stack" marker for Linux }
  1152. if (target_info.system in systems_linux) and
  1153. not(cs_executable_stack in current_settings.moduleswitches) then
  1154. begin
  1155. AsmWriteLn('.section .note.GNU-stack,"",%progbits');
  1156. end;
  1157. AsmLn;
  1158. {$ifdef EXTDEBUG}
  1159. if assigned(current_module.mainsource) then
  1160. Comment(V_Debug,'Done writing gas-styled assembler output for '+current_module.mainsource^);
  1161. {$endif EXTDEBUG}
  1162. end;
  1163. {****************************************************************************}
  1164. { Apple/GNU Assembler writer }
  1165. {****************************************************************************}
  1166. function TAppleGNUAssembler.sectionname(atype:TAsmSectiontype;const aname:string;aorder:TAsmSectionOrder):string;
  1167. begin
  1168. if (target_info.system in systems_darwin) then
  1169. case atype of
  1170. sec_bss:
  1171. { all bss (lcomm) symbols are automatically put in the right }
  1172. { place by using the lcomm assembler directive }
  1173. atype := sec_none;
  1174. sec_debug_frame,
  1175. sec_eh_frame:
  1176. begin
  1177. result := '.section __DWARF,__debug_info,regular,debug';
  1178. exit;
  1179. end;
  1180. sec_debug_line:
  1181. begin
  1182. result := '.section __DWARF,__debug_line,regular,debug';
  1183. exit;
  1184. end;
  1185. sec_debug_info:
  1186. begin
  1187. result := '.section __DWARF,__debug_info,regular,debug';
  1188. exit;
  1189. end;
  1190. sec_debug_abbrev:
  1191. begin
  1192. result := '.section __DWARF,__debug_abbrev,regular,debug';
  1193. exit;
  1194. end;
  1195. sec_rodata:
  1196. begin
  1197. result := '.const_data';
  1198. exit;
  1199. end;
  1200. sec_rodata_norel:
  1201. begin
  1202. result := '.const';
  1203. exit;
  1204. end;
  1205. sec_fpc:
  1206. begin
  1207. result := '.section __TEXT, .fpc, regular, no_dead_strip';
  1208. exit;
  1209. end;
  1210. sec_code:
  1211. begin
  1212. if (aname='fpc_geteipasebx') or
  1213. (aname='fpc_geteipasecx') then
  1214. begin
  1215. result:='.section __TEXT,__textcoal_nt,coalesced,pure_instructions'#10'.weak_definition '+aname+
  1216. #10'.private_extern '+aname;
  1217. exit;
  1218. end;
  1219. end;
  1220. sec_data_nonlazy:
  1221. begin
  1222. result:='.section __DATA, __nl_symbol_ptr,non_lazy_symbol_pointers';
  1223. exit;
  1224. end;
  1225. sec_data_lazy:
  1226. begin
  1227. result:='.section __DATA, __la_symbol_ptr,lazy_symbol_pointers';
  1228. exit;
  1229. end;
  1230. sec_init_func:
  1231. begin
  1232. result:='.section __DATA, __mod_init_func, mod_init_funcs';
  1233. exit;
  1234. end;
  1235. sec_term_func:
  1236. begin
  1237. result:='.section __DATA, __mod_term_func, mod_term_funcs';
  1238. exit;
  1239. end;
  1240. sec_objc_protocol_ext:
  1241. begin
  1242. result:='.section __OBJC, __protocol_ext, regular, no_dead_strip';
  1243. exit;
  1244. end;
  1245. sec_objc_class_ext:
  1246. begin
  1247. result:='.section __OBJC, __class_ext, regular, no_dead_strip';
  1248. exit;
  1249. end;
  1250. sec_objc_property:
  1251. begin
  1252. result:='.section __OBJC, __property, regular, no_dead_strip';
  1253. exit;
  1254. end;
  1255. sec_objc_image_info:
  1256. begin
  1257. result:='.section __OBJC, __image_info, regular, no_dead_strip';
  1258. exit;
  1259. end;
  1260. sec_objc_cstring_object:
  1261. begin
  1262. result:='.section __OBJC, __cstring_object, regular, no_dead_strip';
  1263. exit;
  1264. end;
  1265. sec_objc_sel_fixup:
  1266. begin
  1267. result:='.section __OBJC, __sel_fixup, regular, no_dead_strip';
  1268. exit;
  1269. end;
  1270. sec_objc_message_refs:
  1271. begin
  1272. if (target_info.system in systems_objc_nfabi) then
  1273. begin
  1274. result:='.section __DATA, __objc_selrefs, literal_pointers, no_dead_strip';
  1275. exit;
  1276. end;
  1277. end;
  1278. sec_objc_cls_refs:
  1279. begin
  1280. if (target_info.system in systems_objc_nfabi) then
  1281. begin
  1282. result:='.section __DATA, __objc_clsrefs, regular, no_dead_strip';
  1283. exit;
  1284. end;
  1285. end;
  1286. sec_objc_meth_var_names,
  1287. sec_objc_class_names:
  1288. begin
  1289. if (target_info.system in systems_objc_nfabi) then
  1290. begin
  1291. result:='.cstring';
  1292. exit
  1293. end;
  1294. end;
  1295. sec_objc_inst_meth,
  1296. sec_objc_cls_meth,
  1297. sec_objc_cat_inst_meth,
  1298. sec_objc_cat_cls_meth:
  1299. begin
  1300. if (target_info.system in systems_objc_nfabi) then
  1301. begin
  1302. result:='.section __DATA, __objc_const';
  1303. exit;
  1304. end;
  1305. end;
  1306. sec_objc_meta_class,
  1307. sec_objc_class:
  1308. begin
  1309. if (target_info.system in systems_objc_nfabi) then
  1310. begin
  1311. result:='.section __DATA, __objc_data';
  1312. exit;
  1313. end;
  1314. end;
  1315. sec_objc_sup_refs:
  1316. begin
  1317. result:='.section __DATA, __objc_superrefs, regular, no_dead_strip';
  1318. exit
  1319. end;
  1320. sec_objc_classlist:
  1321. begin
  1322. result:='.section __DATA, __objc_classlist, regular, no_dead_strip';
  1323. exit
  1324. end;
  1325. sec_objc_nlclasslist:
  1326. begin
  1327. result:='.section __DATA, __objc_nlclasslist, regular, no_dead_strip';
  1328. exit
  1329. end;
  1330. sec_objc_catlist:
  1331. begin
  1332. result:='.section __DATA, __objc_catlist, regular, no_dead_strip';
  1333. exit
  1334. end;
  1335. sec_objc_nlcatlist:
  1336. begin
  1337. result:='.section __DATA, __objc_nlcatlist, regular, no_dead_strip';
  1338. exit
  1339. end;
  1340. sec_objc_protolist:
  1341. begin
  1342. result:='.section __DATA, __objc_protolist, coalesced, no_dead_strip';
  1343. exit;
  1344. end;
  1345. end;
  1346. result := inherited sectionname(atype,aname,aorder);
  1347. end;
  1348. procedure TAppleGNUAssembler.WriteWeakSymbolDef(s: tasmsymbol);
  1349. begin
  1350. AsmWriteLn(#9'.weak_reference '+s.name);
  1351. end;
  1352. {****************************************************************************}
  1353. { a.out/GNU Assembler writer }
  1354. {****************************************************************************}
  1355. function TAoutGNUAssembler.sectionname(atype:TAsmSectiontype;const aname:string;aorder:TAsmSectionOrder):string;
  1356. const
  1357. (* Translation table - replace unsupported section types with basic ones. *)
  1358. SecXTable: array[TAsmSectionType] of TAsmSectionType = (
  1359. sec_none,
  1360. sec_none,
  1361. sec_code,
  1362. sec_data,
  1363. sec_data (* sec_rodata *),
  1364. sec_data (* sec_rodata_norel *),
  1365. sec_bss,
  1366. sec_data (* sec_threadvar *),
  1367. { used for wince exception handling }
  1368. sec_code (* sec_pdata *),
  1369. { used for darwin import stubs }
  1370. sec_code (* sec_stub *),
  1371. sec_data,(* sec_data_nonlazy *)
  1372. sec_data,(* sec_data_lazy *)
  1373. sec_data,(* sec_init_func *)
  1374. sec_data,(* sec_term_func *)
  1375. { stabs }
  1376. sec_stab,sec_stabstr,
  1377. { win32 }
  1378. sec_data (* sec_idata2 *),
  1379. sec_data (* sec_idata4 *),
  1380. sec_data (* sec_idata5 *),
  1381. sec_data (* sec_idata6 *),
  1382. sec_data (* sec_idata7 *),
  1383. sec_data (* sec_edata *),
  1384. { C++ exception handling unwinding (uses dwarf) }
  1385. sec_eh_frame,
  1386. { dwarf }
  1387. sec_debug_frame,
  1388. sec_debug_info,
  1389. sec_debug_line,
  1390. sec_debug_abbrev,
  1391. { ELF resources (+ references to stabs debug information sections) }
  1392. sec_code (* sec_fpc *),
  1393. { Table of contents section }
  1394. sec_code (* sec_toc *),
  1395. sec_code (* sec_init *),
  1396. sec_code (* sec_fini *),
  1397. sec_none (* sec_objc_class *),
  1398. sec_none (* sec_objc_meta_class *),
  1399. sec_none (* sec_objc_cat_cls_meth *),
  1400. sec_none (* sec_objc_cat_inst_meth *),
  1401. sec_none (* sec_objc_protocol *),
  1402. sec_none (* sec_objc_string_object *),
  1403. sec_none (* sec_objc_cls_meth *),
  1404. sec_none (* sec_objc_inst_meth *),
  1405. sec_none (* sec_objc_cls_refs *),
  1406. sec_none (* sec_objc_message_refs *),
  1407. sec_none (* sec_objc_symbols *),
  1408. sec_none (* sec_objc_category *),
  1409. sec_none (* sec_objc_class_vars *),
  1410. sec_none (* sec_objc_instance_vars *),
  1411. sec_none (* sec_objc_module_info *),
  1412. sec_none (* sec_objc_class_names *),
  1413. sec_none (* sec_objc_meth_var_types *),
  1414. sec_none (* sec_objc_meth_var_names *),
  1415. sec_none (* sec_objc_selector_strs *),
  1416. sec_none (* sec_objc_protocol_ext *),
  1417. sec_none (* sec_objc_class_ext *),
  1418. sec_none (* sec_objc_property *),
  1419. sec_none (* sec_objc_image_info *),
  1420. sec_none (* sec_objc_cstring_object *),
  1421. sec_none (* sec_objc_sel_fixup *),
  1422. sec_none (* sec_objc_data *),
  1423. sec_none (* sec_objc_const *),
  1424. sec_none (* sec_objc_sup_refs *),
  1425. sec_none (* sec_data_coalesced *),
  1426. sec_none (* sec_objc_classlist *),
  1427. sec_none (* sec_objc_nlclasslist *),
  1428. sec_none (* sec_objc_catlist *),
  1429. sec_none (* sec_objc_nlcatlist *),
  1430. sec_none (* sec_objc_protlist *)
  1431. );
  1432. begin
  1433. Result := inherited SectionName (SecXTable [AType], AName, AOrder);
  1434. end;
  1435. {****************************************************************************}
  1436. { Abstract Instruction Writer }
  1437. {****************************************************************************}
  1438. constructor TCPUInstrWriter.create(_owner: TGNUAssembler);
  1439. begin
  1440. inherited create;
  1441. owner := _owner;
  1442. end;
  1443. end.