aasm.pas 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769
  1. {
  2. $Id$
  3. Copyright (c) 1996-98 by Florian Klaempfl
  4. This unit implements an abstract asmoutput class for all processor types
  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. unit aasm;
  19. interface
  20. uses
  21. cobjects,files,globals;
  22. {$I version.inc}
  23. type
  24. tait = (
  25. ait_string,
  26. ait_label,
  27. ait_direct,
  28. ait_labeled_instruction,
  29. ait_comment,
  30. ait_instruction,
  31. ait_datablock,
  32. ait_symbol,
  33. ait_const_32bit,
  34. ait_const_symbol,
  35. ait_const_16bit,
  36. ait_const_8bit,
  37. ait_real_64bit,
  38. ait_real_32bit,
  39. ait_real_extended,
  40. ait_comp,
  41. ait_external,
  42. ait_align,
  43. { the following is only used by the win32 version of the compiler }
  44. { and only the GNU AS Win32 is able to write it }
  45. ait_section,
  46. ait_const_rva,
  47. { the following must is system depended }
  48. {$ifdef GDB}
  49. ait_stabn,
  50. ait_stabs,
  51. ait_stab_function_name,
  52. {$endif GDB}
  53. {$ifdef MAKELIB}
  54. { used to split unit into tiny assembler files }
  55. ait_cut,
  56. {$endif MAKELIB}
  57. { never used, makes insertation of new ait_ easier to type }
  58. {$ifdef REGALLOC}
  59. ait_regalloc,
  60. ait_regdealloc,
  61. {$endif REGALLOC}
  62. ait_dummy);
  63. type
  64. { the short name makes typing easier }
  65. pai = ^tai;
  66. tai = object(tlinkedlist_item)
  67. typ : tait;
  68. line : longint;
  69. infile : pinputfile;
  70. constructor init;
  71. end;
  72. pai_string = ^tai_string;
  73. tai_string = object(tai)
  74. str : pchar;
  75. { extra len so the string can contain an \0 }
  76. len : longint;
  77. constructor init(const _str : string);
  78. constructor init_pchar(_str : pchar);
  79. destructor done;virtual;
  80. end;
  81. pai_symbol = ^tai_symbol;
  82. { generates a common label }
  83. tai_symbol = object(tai)
  84. name : pchar;
  85. is_global : boolean;
  86. constructor init(const _name : string);
  87. constructor init_global(const _name : string);
  88. destructor done;virtual;
  89. end;
  90. { external types defined for TASM }
  91. { EXT_ANY for search purposes }
  92. texternal_typ = (EXT_ANY,EXT_NEAR, EXT_FAR, EXT_PROC, EXT_BYTE,
  93. EXT_WORD, EXT_DWORD, EXT_CODEPTR, EXT_DATAPTR,
  94. EXT_FWORD, EXT_PWORD, EXT_QWORD, EXT_TBYTE, EXT_ABS);
  95. pai_external = ^tai_external;
  96. { generates an symbol which is marked as external }
  97. tai_external = object(tai)
  98. name : pchar;
  99. exttyp : texternal_typ;
  100. constructor init(const _name : string;exttype : texternal_typ);
  101. destructor done; virtual;
  102. end;
  103. { simple temporary label }
  104. pai_label = ^tai_label;
  105. { type for a temporary label }
  106. { test if used for dispose of unnecessary labels }
  107. tlabel = record
  108. nb : longint;
  109. is_used : boolean;
  110. is_set : boolean;
  111. refcount : word;
  112. end;
  113. plabel = ^tlabel;
  114. tai_label = object(tai)
  115. l : plabel;
  116. constructor init(_l : plabel);
  117. destructor done; virtual;
  118. end;
  119. pai_direct = ^tai_direct;
  120. tai_direct = object(tai)
  121. str : pchar;
  122. constructor init(_str : pchar);
  123. destructor done; virtual;
  124. end;
  125. { alignment for operator }
  126. pai_align = ^tai_align;
  127. tai_align = object(tai)
  128. aligntype: byte; { 1 = no align, 2 = word align, 4 = dword align }
  129. op: byte; { value to fill with - optional }
  130. constructor init(b:byte);
  131. constructor init_op(b: byte; use_op: byte);
  132. destructor done;virtual;
  133. end;
  134. pai_section = ^tai_section;
  135. tai_section = object(tai)
  136. name : pstring;
  137. constructor init(const s : string);
  138. destructor done;virtual;
  139. end;
  140. pai_datablock = ^tai_datablock;
  141. { generates an uninitilizised data block }
  142. tai_datablock = object(tai)
  143. size : longint;
  144. name : pchar;
  145. is_global : boolean;
  146. constructor init(const _name : string;_size : longint);
  147. constructor init_global(const _name : string;_size : longint);
  148. destructor done; virtual;
  149. end;
  150. pai_const = ^tai_const;
  151. { generates a long integer (32 bit) }
  152. tai_const = object(tai)
  153. value : longint;
  154. constructor init_32bit(_value : longint);
  155. constructor init_16bit(_value : word);
  156. constructor init_8bit(_value : byte);
  157. constructor init_symbol(p : pchar);
  158. constructor init_rva(p : pchar);
  159. destructor done;virtual;
  160. end;
  161. pai_double = ^tai_double;
  162. { generates a double (64 bit real) }
  163. tai_double = object(tai)
  164. value : double;
  165. constructor init(_value : double);
  166. end;
  167. pai_single = ^tai_single;
  168. { generates a single (32 bit real) }
  169. tai_single = object(tai)
  170. value : single;
  171. constructor init(_value : single);
  172. end;
  173. pai_extended = ^tai_extended;
  174. { generates an extended (80 bit real) }
  175. { for version above v0_9_8 }
  176. { creates a double otherwise }
  177. tai_extended = object(tai)
  178. value : bestreal;
  179. constructor init(_value : bestreal);
  180. end;
  181. {$ifdef MAKELIB}
  182. pai_cut = ^tai_cut;
  183. tai_cut = object(tai)
  184. constructor init;
  185. end;
  186. {$endif MAKELIB}
  187. { for each processor define the best precision }
  188. { bestreal is defined in globals }
  189. {$ifdef i386}
  190. {$ifdef ver_above0_9_8}
  191. const
  192. ait_bestreal = ait_real_extended;
  193. type
  194. pai_bestreal = pai_extended;
  195. tai_bestreal = tai_extended;
  196. {$else ver_above0_9_8}
  197. const
  198. ait_bestreal = ait_real_64bit;
  199. type
  200. pai_bestreal = pai_double;
  201. tai_bestreal = tai_double;
  202. {$endif ver_above0_9_8}
  203. {$endif i386}
  204. {$ifdef m68k}
  205. const
  206. ait_bestreal = ait_real_32bit;
  207. type
  208. pai_bestreal = pai_single;
  209. tai_bestreal = tai_single;
  210. {$endif m68k}
  211. pai_comp = ^tai_comp;
  212. { generates an comp (integer over 64 bits) }
  213. tai_comp = object(tai)
  214. value : bestreal;
  215. constructor init(_value : bestreal);
  216. end;
  217. paasmoutput = ^taasmoutput;
  218. taasmoutput = tlinkedlist;
  219. var
  220. datasegment,codesegment,bsssegment,
  221. internals,externals,debuglist,consts,importssection,
  222. exportssection,resourcesection : paasmoutput;
  223. { external symbols without repetition }
  224. function search_assembler_symbol(pl : paasmoutput;const _name : string;exttype : texternal_typ) : pai_external;
  225. procedure concat_external(const _name : string;exttype : texternal_typ);
  226. procedure concat_internal(const _name : string;exttype : texternal_typ);
  227. implementation
  228. uses strings,verbose;
  229. {****************************************************************************
  230. TAI
  231. ****************************************************************************}
  232. constructor tai.init;
  233. begin
  234. {$ifdef GDB}
  235. infile:=pointer(current_module^.current_inputfile);
  236. if assigned(infile) then
  237. line:=current_module^.current_inputfile^.line_no;
  238. {$endif GDB}
  239. end;
  240. {****************************************************************************
  241. TAI_SECTION
  242. ****************************************************************************}
  243. constructor tai_section.init(const s : string);
  244. begin
  245. inherited init;
  246. typ:=ait_section;
  247. name:=stringdup(s);
  248. end;
  249. destructor tai_section.done;
  250. begin
  251. stringdispose(name);
  252. inherited done;
  253. end;
  254. {****************************************************************************
  255. TAI_DATABLOCK
  256. ****************************************************************************}
  257. constructor tai_datablock.init(const _name : string;_size : longint);
  258. begin
  259. inherited init;
  260. typ:=ait_datablock;
  261. name:=strpnew(_name);
  262. concat_internal(_name,EXT_ANY);
  263. size:=_size;
  264. is_global:=false;
  265. end;
  266. constructor tai_datablock.init_global(const _name : string;_size : longint);
  267. begin
  268. inherited init;
  269. typ:=ait_datablock;
  270. name:=strpnew(_name);
  271. concat_internal(_name,EXT_ANY);
  272. size:=_size;
  273. is_global:=true;
  274. end;
  275. destructor tai_datablock.done;
  276. begin
  277. strdispose(name);
  278. inherited done;
  279. end;
  280. {****************************************************************************
  281. TAI_SYMBOL
  282. ****************************************************************************}
  283. constructor tai_symbol.init(const _name : string);
  284. begin
  285. inherited init;
  286. typ:=ait_symbol;
  287. name:=strpnew(_name);
  288. concat_internal(_name,EXT_ANY);
  289. is_global:=false;
  290. end;
  291. constructor tai_symbol.init_global(const _name : string);
  292. begin
  293. inherited init;
  294. typ:=ait_symbol;
  295. name:=strpnew(_name);
  296. concat_internal(_name,EXT_ANY);
  297. is_global:=true;
  298. end;
  299. destructor tai_symbol.done;
  300. begin
  301. strdispose(name);
  302. inherited done;
  303. end;
  304. {****************************************************************************
  305. TAI_EXTERNAL
  306. ****************************************************************************}
  307. constructor tai_external.init(const _name : string;exttype : texternal_typ);
  308. begin
  309. inherited init;
  310. typ:=ait_external;
  311. exttyp:=exttype;
  312. name:=strpnew(_name);
  313. end;
  314. destructor tai_external.done;
  315. begin
  316. strdispose(name);
  317. inherited done;
  318. end;
  319. function search_assembler_symbol(pl : paasmoutput;const _name : string;exttype : texternal_typ) : pai_external;
  320. var
  321. p : pai;
  322. begin
  323. search_assembler_symbol:=nil;
  324. if pl=nil then
  325. internalerror(2001)
  326. else
  327. begin
  328. p:=pai(pl^.first);
  329. while (p<>nil) and
  330. (p<>pai(pl^.last)) do
  331. { if we get the same name with a different typ }
  332. { there is probably an error }
  333. if (p^.typ=ait_external) and
  334. ((exttype=EXT_ANY) or (pai_external(p)^.exttyp=exttype)) and
  335. (strpas(pai_external(p)^.name)=_name) then
  336. begin
  337. search_assembler_symbol:=pai_external(p);
  338. exit;
  339. end
  340. else
  341. p:=pai(p^.next);
  342. if (p<>nil) and
  343. (p^.typ=ait_external) and
  344. (pai_external(p)^.exttyp=exttype) and
  345. (strpas(pai_external(p)^.name)=_name) then
  346. begin
  347. search_assembler_symbol:=pai_external(p);
  348. exit;
  349. end;
  350. end;
  351. end;
  352. { insert each need external only once }
  353. procedure concat_external(const _name : string;exttype : texternal_typ);
  354. var
  355. p : pai_external;
  356. begin
  357. p:=search_assembler_symbol(externals,_name,exttype);
  358. if p=nil then
  359. externals^.concat(new(pai_external,init(_name,exttype)));
  360. end;
  361. { insert each need external only once }
  362. procedure concat_internal(const _name : string;exttype : texternal_typ);
  363. var
  364. p : pai_external;
  365. begin
  366. p:=search_assembler_symbol(internals,_name,exttype);
  367. if p=nil then
  368. internals^.concat(new(pai_external,init(_name,exttype)));
  369. end;
  370. {****************************************************************************
  371. TAI_CONST
  372. ****************************************************************************}
  373. constructor tai_const.init_32bit(_value : longint);
  374. begin
  375. inherited init;
  376. typ:=ait_const_32bit;
  377. value:=_value;
  378. end;
  379. constructor tai_const.init_16bit(_value : word);
  380. begin
  381. inherited init;
  382. typ:=ait_const_16bit;
  383. value:=_value;
  384. end;
  385. constructor tai_const.init_8bit(_value : byte);
  386. begin
  387. inherited init;
  388. typ:=ait_const_8bit;
  389. value:=_value;
  390. end;
  391. constructor tai_const.init_symbol(p : pchar);
  392. begin
  393. inherited init;
  394. typ:=ait_const_symbol;
  395. value:=longint(p);
  396. end;
  397. constructor tai_const.init_rva(p : pchar);
  398. begin
  399. inherited init;
  400. typ:=ait_const_rva;
  401. value:=longint(p);
  402. end;
  403. destructor tai_const.done;
  404. begin
  405. if typ=ait_const_symbol then
  406. strdispose(pchar(value));
  407. inherited done;
  408. end;
  409. {****************************************************************************
  410. TAI_DOUBLE
  411. ****************************************************************************}
  412. constructor tai_double.init(_value : double);
  413. begin
  414. inherited init;
  415. typ:=ait_real_64bit;
  416. value:=_value;
  417. end;
  418. {****************************************************************************
  419. TAI_SINGLE
  420. ****************************************************************************}
  421. constructor tai_single.init(_value : single);
  422. begin
  423. inherited init;
  424. typ:=ait_real_32bit;
  425. value:=_value;
  426. end;
  427. {****************************************************************************
  428. TAI_EXTENDED
  429. ****************************************************************************}
  430. constructor tai_extended.init(_value : bestreal);
  431. begin
  432. inherited init;
  433. typ:=ait_real_extended;
  434. value:=_value;
  435. end;
  436. {****************************************************************************
  437. TAI_COMP
  438. ****************************************************************************}
  439. constructor tai_comp.init(_value : bestreal);
  440. begin
  441. inherited init;
  442. typ:=ait_comp;
  443. value:=_value;
  444. end;
  445. {****************************************************************************
  446. TAI_STRING
  447. ****************************************************************************}
  448. constructor tai_string.init(const _str : string);
  449. begin
  450. inherited init;
  451. typ:=ait_string;
  452. getmem(str,length(_str)+1);
  453. strpcopy(str,_str);
  454. len:=length(_str);
  455. end;
  456. constructor tai_string.init_pchar(_str : pchar);
  457. begin
  458. inherited init;
  459. typ:=ait_string;
  460. str:=_str;
  461. len:=strlen(_str);
  462. end;
  463. destructor tai_string.done;
  464. begin
  465. { you can have #0 inside the strings so }
  466. if str<>nil then
  467. freemem(str,len+1);
  468. inherited done;
  469. end;
  470. {****************************************************************************
  471. TAI_LABEL
  472. ****************************************************************************}
  473. constructor tai_label.init(_l : plabel);
  474. begin
  475. inherited init;
  476. typ:=ait_label;
  477. l:=_l;
  478. l^.is_set:=true;
  479. { suggestion of JM:
  480. inc(l^.refcount); }
  481. end;
  482. destructor tai_label.done;
  483. begin
  484. { suggestion of JM:
  485. dec(l^.refcount); }
  486. if (l^.is_used) then
  487. l^.is_set:=false
  488. else dispose(l);
  489. inherited done;
  490. end;
  491. {****************************************************************************
  492. TAI_DIRECT
  493. ****************************************************************************}
  494. constructor tai_direct.init(_str : pchar);
  495. begin
  496. inherited init;
  497. typ:=ait_direct;
  498. str:=_str;
  499. end;
  500. destructor tai_direct.done;
  501. begin
  502. strdispose(str);
  503. inherited done;
  504. end;
  505. {****************************************************************************
  506. TAI_ALIGN
  507. ****************************************************************************}
  508. constructor tai_align.init(b: byte);
  509. begin
  510. inherited init;
  511. typ:=ait_align;
  512. if b in [1,2,4,8,16] then
  513. aligntype := b
  514. else
  515. aligntype := 1;
  516. op:=0;
  517. end;
  518. constructor tai_align.init_op(b: byte; use_op: byte);
  519. begin
  520. inherited init;
  521. typ:=ait_align;
  522. if b in [1,2,4,8,16] then
  523. aligntype := b
  524. else
  525. aligntype := 1;
  526. op:=use_op;
  527. end;
  528. destructor tai_align.done;
  529. begin
  530. inherited done;
  531. end;
  532. {$ifdef MAKELIB}
  533. {****************************************************************************
  534. TAI_CUT
  535. ****************************************************************************}
  536. constructor tai_cut.init;
  537. begin
  538. inherited init;
  539. typ:=ait_cut;
  540. end;
  541. {$endif MAKELIB}
  542. end.
  543. {
  544. $Log$
  545. Revision 1.2 1998-04-09 15:46:37 florian
  546. + register allocation tracing stuff added
  547. Revision 1.1.1.1 1998/03/25 11:18:16 root
  548. * Restored version
  549. Revision 1.18 1998/03/10 16:27:36 pierre
  550. * better line info in stabs debug
  551. * symtabletype and lexlevel separated into two fields of tsymtable
  552. + ifdef MAKELIB for direct library output, not complete
  553. + ifdef CHAINPROCSYMS for overloaded seach across units, not fully
  554. working
  555. + ifdef TESTFUNCRET for setting func result in underfunction, not
  556. working
  557. Revision 1.17 1998/03/10 01:17:13 peter
  558. * all files have the same header
  559. * messages are fully implemented, EXTDEBUG uses Comment()
  560. + AG... files for the Assembler generation
  561. Revision 1.16 1998/03/02 01:47:56 peter
  562. * renamed target_DOS to target_GO32V1
  563. + new verbose system, merged old errors and verbose units into one new
  564. verbose.pas, so errors.pas is obsolete
  565. Revision 1.15 1998/02/28 14:43:46 florian
  566. * final implemenation of win32 imports
  567. * extended tai_align to allow 8 and 16 byte aligns
  568. Revision 1.14 1998/02/28 00:20:20 florian
  569. * more changes to get import libs for Win32 working
  570. Revision 1.13 1998/02/27 22:27:50 florian
  571. + win_targ unit
  572. + support of sections
  573. + new asmlists: sections, exports and resource
  574. Revision 1.12 1998/02/24 00:19:08 peter
  575. * makefile works again (btw. linux does like any char after a \ )
  576. * removed circular unit with assemble and files
  577. * fixed a sigsegv in pexpr
  578. * pmodule init unit/program is the almost the same, merged them
  579. Revision 1.11 1998/02/13 10:34:29 daniel
  580. * Made Motorola version compilable.
  581. * Fixed optimizer
  582. Revision 1.10 1998/02/06 23:08:31 florian
  583. + endian to targetinfo and sourceinfo added
  584. + endian independed writing of ppu file (reading missed), a PPU file
  585. is written with the target endian
  586. Revision 1.9 1998/01/11 04:14:30 carl
  587. + correct floating point support for m68k
  588. Revision 1.6 1997/12/09 13:18:34 carl
  589. + added pai_align abstract object (required for m68k)
  590. + renamed ait_real_s80bit --> ait_real_extended
  591. Revision 1.5 1997/12/01 18:14:32 pierre
  592. * fixes a bug in nasm output due to my previous changes
  593. Revision 1.3 1997/11/28 18:14:17 pierre
  594. working version with several bug fixes
  595. Revision 1.2 1997/11/28 14:26:18 florian
  596. Fixed some bugs
  597. Revision 1.1.1.1 1997/11/27 08:32:50 michael
  598. FPC Compiler CVS start
  599. Pre-CVS log:
  600. FK Florian Klaempfl
  601. PM Pierre Muller
  602. + feature added
  603. - removed
  604. * bug fixed or changed
  605. History:
  606. 30th september 1996:
  607. + unit started
  608. 13th november 1997:
  609. + added pai_single and pai_extended (PM)
  610. 14th november 1997:
  611. + added bestreal type and pai_bestreal
  612. to store all real consts with best precision (PM)
  613. has a drawback for GDB that does not know extended !! (PM)
  614. }