aasmtai.pas 29 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031
  1. {
  2. $Id$
  3. Copyright (c) 1998-2002 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. {# @abstract(This unit implements an abstract asm output class for all processor types)
  19. This unit implements an abstract assembler output class for all processors, these
  20. are then overriden for each assembler writer to actually write the data in these
  21. classes to an assembler file.
  22. }
  23. unit aasmtai;
  24. {$i fpcdefs.inc}
  25. interface
  26. uses
  27. cutils,cclasses,
  28. globtype,globals,systems,
  29. cpuinfo,cpubase,
  30. aasmbase;
  31. type
  32. tait = (
  33. ait_none,
  34. ait_direct,
  35. ait_string,
  36. ait_label,
  37. ait_comment,
  38. ait_instruction,
  39. ait_datablock,
  40. ait_symbol,
  41. ait_symbol_end, { needed to calc the size of a symbol }
  42. ait_const_32bit,
  43. ait_const_16bit,
  44. ait_const_8bit,
  45. ait_const_symbol,
  46. ait_real_80bit,
  47. ait_real_64bit,
  48. ait_real_32bit,
  49. ait_comp_64bit,
  50. ait_align,
  51. ait_section,
  52. { the following is only used by the win32 version of the compiler }
  53. { and only the GNU AS Win32 is able to write it }
  54. ait_const_rva,
  55. {$ifdef GDB}
  56. ait_stabn,
  57. ait_stabs,
  58. ait_force_line,
  59. ait_stab_function_name,
  60. {$endif GDB}
  61. ait_cut, { used to split into tiny assembler files }
  62. ait_regalloc,
  63. ait_tempalloc,
  64. ait_marker, { used to mark assembler blocks and inlined functions }
  65. {$ifdef alpha}
  66. { the follow is for the DEC Alpha }
  67. ait_frame,
  68. ait_ent,
  69. {$endif alpha}
  70. {$ifdef m68k}
  71. ait_labeled_instruction,
  72. {$endif m68k}
  73. {$ifdef ia64}
  74. ait_bundle,
  75. ait_stop,
  76. {$endif ia64}
  77. {$ifdef SPARC}
  78. ait_labeled_instruction,
  79. {$endif SPARC}
  80. { never used, makes insertation of new ait_ easier to type }
  81. { lazy guy !!!! ;-) (FK) }
  82. ait_dummy);
  83. { ait_* types which don't result in executable code or which don't influence }
  84. { the way the program runs/behaves, but which may be encountered by the }
  85. { optimizer (= if it's sometimes added to the exprasm list). Update if you add }
  86. { a new ait type! }
  87. const
  88. SkipInstr = [ait_comment, ait_symbol,ait_section
  89. {$ifdef GDB}
  90. ,ait_stabs, ait_stabn, ait_stab_function_name, ait_force_line
  91. {$endif GDB}
  92. ,ait_regalloc, ait_tempalloc, ait_symbol_end];
  93. type
  94. { cut type, required for alphanumeric ordering of the assembler filenames }
  95. TCutPlace=(cut_normal,cut_begin,cut_end);
  96. TMarker = (NoPropInfoStart,NoPropInfoEnd,
  97. AsmBlockStart,AsmBlockEnd,
  98. InlineStart,InlineEnd);
  99. { the short name makes typing easier }
  100. tai = class(TLinkedListItem)
  101. { pointer to record with optimizer info about this tai object }
  102. optinfo : pointer;
  103. fileinfo : tfileposinfo;
  104. typ : tait;
  105. constructor Create;
  106. end;
  107. {# Generates an assembler string }
  108. tai_string = class(tai)
  109. str : pchar;
  110. { extra len so the string can contain an \0 }
  111. len : longint;
  112. constructor Create(const _str : string);
  113. constructor Create_pchar(_str : pchar);
  114. constructor Create_length_pchar(_str : pchar;length : longint);
  115. destructor Destroy;override;
  116. end;
  117. {# Generates a common label }
  118. tai_symbol = class(tai)
  119. is_global : boolean;
  120. sym : tasmsymbol;
  121. size : longint;
  122. constructor Create(_sym:tasmsymbol;siz:longint);
  123. constructor Createname(const _name : string;siz:longint);
  124. constructor Createname_global(const _name : string;siz:longint);
  125. constructor Createdataname(const _name : string;siz:longint);
  126. constructor Createdataname_global(const _name : string;siz:longint);
  127. end;
  128. tai_symbol_end = class(tai)
  129. sym : tasmsymbol;
  130. constructor Create(_sym:tasmsymbol);
  131. constructor Createname(const _name : string);
  132. end;
  133. {# Generates an assembler label }
  134. tai_label = class(tai)
  135. is_global : boolean;
  136. l : tasmlabel;
  137. constructor Create(_l : tasmlabel);
  138. end;
  139. {# Directly output data to final assembler file }
  140. tai_direct = class(tai)
  141. str : pchar;
  142. constructor Create(_str : pchar);
  143. destructor Destroy; override;
  144. end;
  145. {# Generates an assembler comment }
  146. tai_asm_comment = class(tai)
  147. str : pchar;
  148. constructor Create(_str : pchar);
  149. destructor Destroy; override;
  150. end;
  151. {# Generates a section / segment directive }
  152. tai_section = class(tai)
  153. sec : TSection;
  154. constructor Create(s : TSection);
  155. end;
  156. {# Generates an uninitializised data block }
  157. tai_datablock = class(tai)
  158. is_global : boolean;
  159. sym : tasmsymbol;
  160. size : longint;
  161. constructor Create(const _name : string;_size : longint);
  162. constructor Create_global(const _name : string;_size : longint);
  163. end;
  164. {# Generates a long integer (32 bit) }
  165. tai_const = class(tai)
  166. value : longint;
  167. constructor Create_32bit(_value : longint);
  168. constructor Create_16bit(_value : word);
  169. constructor Create_8bit(_value : byte);
  170. end;
  171. tai_const_symbol = class(tai)
  172. sym : tasmsymbol;
  173. offset : longint;
  174. constructor Create(_sym:tasmsymbol);
  175. constructor Create_offset(_sym:tasmsymbol;ofs:longint);
  176. constructor Create_rva(_sym:tasmsymbol);
  177. constructor Createname(const name:string);
  178. constructor Createname_offset(const name:string;ofs:longint);
  179. constructor Createname_rva(const name:string);
  180. end;
  181. {# Generates a single float (32 bit real) }
  182. tai_real_32bit = class(tai)
  183. value : ts32real;
  184. constructor Create(_value : ts32real);
  185. end;
  186. {# Generates a double float (64 bit real) }
  187. tai_real_64bit = class(tai)
  188. value : ts64real;
  189. constructor Create(_value : ts64real);
  190. end;
  191. {# Generates an extended float (80 bit real) }
  192. tai_real_80bit = class(tai)
  193. value : ts80real;
  194. constructor Create(_value : ts80real);
  195. end;
  196. {# Generates a comp int (integer over 64 bits)
  197. This is Intel 80x86 specific, and is not
  198. really supported on other processors.
  199. }
  200. tai_comp_64bit = class(tai)
  201. value : ts64comp;
  202. constructor Create(_value : ts64comp);
  203. end;
  204. {# Insert a cut to split assembler into several smaller files }
  205. tai_cut = class(tai)
  206. place : tcutplace;
  207. constructor Create;
  208. constructor Create_begin;
  209. constructor Create_end;
  210. end;
  211. {# Insert a marker for assembler and inline blocks }
  212. tai_marker = class(tai)
  213. Kind: TMarker;
  214. Constructor Create(_Kind: TMarker);
  215. end;
  216. tai_tempalloc = class(tai)
  217. allocation : boolean;
  218. temppos,
  219. tempsize : longint;
  220. constructor alloc(pos,size:longint);
  221. constructor dealloc(pos,size:longint);
  222. end;
  223. tai_regalloc = class(tai)
  224. allocation : boolean;
  225. reg : tregister;
  226. constructor alloc(r : tregister);
  227. constructor dealloc(r : tregister);
  228. end;
  229. {# Class template for assembler instructions
  230. }
  231. taicpu_abstract = class(tai)
  232. {# Condition flags for instruction }
  233. condition : TAsmCond;
  234. {# Number of operands to instruction }
  235. ops : longint;
  236. {# Operands of instruction }
  237. oper : array[0..max_operands-1] of toper;
  238. {# Actual opcode of instruction }
  239. opcode : tasmop;
  240. {$ifdef i386}
  241. segprefix : tregister;
  242. {$endif i386}
  243. {# true if instruction is a jmp }
  244. is_jmp : boolean; { is this instruction a jump? (needed for optimizer) }
  245. Constructor Create(op : tasmop);
  246. Destructor Destroy;override;
  247. function getcopy:TLinkedListItem;override;
  248. procedure loadconst(opidx:longint;l:aword);
  249. procedure loadsymbol(opidx:longint;s:tasmsymbol;sofs:longint);
  250. procedure loadref(opidx:longint;const r:treference);
  251. procedure loadreg(opidx:longint;r:tregister);
  252. procedure loadoper(opidx:longint;o:toper);
  253. procedure SetCondition(const c:TAsmCond);
  254. end;
  255. {# alignment for operator }
  256. tai_align_abstract = class(tai)
  257. buf : array[0..63] of char; { buf used for fill }
  258. aligntype : byte; { 1 = no align, 2 = word align, 4 = dword align }
  259. fillsize : byte; { real size to fill }
  260. fillop : byte; { value to fill with - optional }
  261. use_op : boolean;
  262. constructor Create(b:byte);
  263. constructor Create_op(b: byte; _op: byte);
  264. function getfillbuf:pchar;virtual;
  265. end;
  266. taasmoutput = class(tlinkedlist)
  267. function getlasttaifilepos : pfileposinfo;
  268. end;
  269. var
  270. { temporary lists }
  271. exprasmlist,
  272. { default lists }
  273. datasegment,codesegment,bsssegment,
  274. debuglist,withdebuglist,consts,
  275. importssection,exportssection,
  276. resourcesection,rttilist,
  277. resourcestringlist : taasmoutput;
  278. implementation
  279. uses
  280. {$ifdef delphi}
  281. sysutils,
  282. {$else}
  283. strings,
  284. {$endif}
  285. verbose;
  286. {****************************************************************************
  287. TAI
  288. ****************************************************************************}
  289. constructor tai.Create;
  290. begin
  291. optinfo := nil;
  292. fileinfo:=aktfilepos;
  293. end;
  294. {****************************************************************************
  295. TAI_SECTION
  296. ****************************************************************************}
  297. constructor tai_section.Create(s : TSection);
  298. begin
  299. inherited Create;
  300. typ:=ait_section;
  301. sec:=s;
  302. end;
  303. {****************************************************************************
  304. TAI_DATABLOCK
  305. ****************************************************************************}
  306. constructor tai_datablock.Create(const _name : string;_size : longint);
  307. begin
  308. inherited Create;
  309. typ:=ait_datablock;
  310. sym:=objectlibrary.newasmsymboltype(_name,AB_LOCAL,AT_DATA);
  311. { keep things aligned }
  312. if _size<=0 then
  313. _size:=4;
  314. size:=_size;
  315. is_global:=false;
  316. end;
  317. constructor tai_datablock.Create_global(const _name : string;_size : longint);
  318. begin
  319. inherited Create;
  320. typ:=ait_datablock;
  321. sym:=objectlibrary.newasmsymboltype(_name,AB_GLOBAL,AT_DATA);
  322. { keep things aligned }
  323. if _size<=0 then
  324. _size:=4;
  325. size:=_size;
  326. is_global:=true;
  327. end;
  328. {****************************************************************************
  329. TAI_SYMBOL
  330. ****************************************************************************}
  331. constructor tai_symbol.Create(_sym:tasmsymbol;siz:longint);
  332. begin
  333. inherited Create;
  334. typ:=ait_symbol;
  335. sym:=_sym;
  336. size:=siz;
  337. is_global:=(sym.defbind=AB_GLOBAL);
  338. end;
  339. constructor tai_symbol.Createname(const _name : string;siz:longint);
  340. begin
  341. inherited Create;
  342. typ:=ait_symbol;
  343. sym:=objectlibrary.newasmsymboltype(_name,AB_LOCAL,AT_FUNCTION);
  344. size:=siz;
  345. is_global:=false;
  346. end;
  347. constructor tai_symbol.Createname_global(const _name : string;siz:longint);
  348. begin
  349. inherited Create;
  350. typ:=ait_symbol;
  351. sym:=objectlibrary.newasmsymboltype(_name,AB_GLOBAL,AT_FUNCTION);
  352. size:=siz;
  353. is_global:=true;
  354. end;
  355. constructor tai_symbol.Createdataname(const _name : string;siz:longint);
  356. begin
  357. inherited Create;
  358. typ:=ait_symbol;
  359. sym:=objectlibrary.newasmsymboltype(_name,AB_LOCAL,AT_DATA);
  360. size:=siz;
  361. is_global:=false;
  362. end;
  363. constructor tai_symbol.Createdataname_global(const _name : string;siz:longint);
  364. begin
  365. inherited Create;
  366. typ:=ait_symbol;
  367. sym:=objectlibrary.newasmsymboltype(_name,AB_GLOBAL,AT_DATA);
  368. size:=siz;
  369. is_global:=true;
  370. end;
  371. {****************************************************************************
  372. TAI_SYMBOL
  373. ****************************************************************************}
  374. constructor tai_symbol_end.Create(_sym:tasmsymbol);
  375. begin
  376. inherited Create;
  377. typ:=ait_symbol_end;
  378. sym:=_sym;
  379. end;
  380. constructor tai_symbol_end.Createname(const _name : string);
  381. begin
  382. inherited Create;
  383. typ:=ait_symbol_end;
  384. sym:=objectlibrary.newasmsymboltype(_name,AB_GLOBAL,AT_NONE);
  385. end;
  386. {****************************************************************************
  387. TAI_CONST
  388. ****************************************************************************}
  389. constructor tai_const.Create_32bit(_value : longint);
  390. begin
  391. inherited Create;
  392. typ:=ait_const_32bit;
  393. value:=_value;
  394. end;
  395. constructor tai_const.Create_16bit(_value : word);
  396. begin
  397. inherited Create;
  398. typ:=ait_const_16bit;
  399. value:=_value;
  400. end;
  401. constructor tai_const.Create_8bit(_value : byte);
  402. begin
  403. inherited Create;
  404. typ:=ait_const_8bit;
  405. value:=_value;
  406. end;
  407. {****************************************************************************
  408. TAI_CONST_SYMBOL_OFFSET
  409. ****************************************************************************}
  410. constructor tai_const_symbol.Create(_sym:tasmsymbol);
  411. begin
  412. inherited Create;
  413. typ:=ait_const_symbol;
  414. sym:=_sym;
  415. offset:=0;
  416. { update sym info }
  417. inc(sym.refs);
  418. end;
  419. constructor tai_const_symbol.Create_offset(_sym:tasmsymbol;ofs:longint);
  420. begin
  421. inherited Create;
  422. typ:=ait_const_symbol;
  423. sym:=_sym;
  424. offset:=ofs;
  425. { update sym info }
  426. inc(sym.refs);
  427. end;
  428. constructor tai_const_symbol.Create_rva(_sym:tasmsymbol);
  429. begin
  430. inherited Create;
  431. typ:=ait_const_rva;
  432. sym:=_sym;
  433. offset:=0;
  434. { update sym info }
  435. inc(sym.refs);
  436. end;
  437. constructor tai_const_symbol.Createname(const name:string);
  438. begin
  439. inherited Create;
  440. typ:=ait_const_symbol;
  441. sym:=objectlibrary.newasmsymbol(name);
  442. offset:=0;
  443. { update sym info }
  444. inc(sym.refs);
  445. end;
  446. constructor tai_const_symbol.Createname_offset(const name:string;ofs:longint);
  447. begin
  448. inherited Create;
  449. typ:=ait_const_symbol;
  450. sym:=objectlibrary.newasmsymbol(name);
  451. offset:=ofs;
  452. { update sym info }
  453. inc(sym.refs);
  454. end;
  455. constructor tai_const_symbol.Createname_rva(const name:string);
  456. begin
  457. inherited Create;
  458. typ:=ait_const_rva;
  459. sym:=objectlibrary.newasmsymbol(name);
  460. offset:=0;
  461. { update sym info }
  462. inc(sym.refs);
  463. end;
  464. {****************************************************************************
  465. TAI_real_32bit
  466. ****************************************************************************}
  467. constructor tai_real_32bit.Create(_value : ts32real);
  468. begin
  469. inherited Create;
  470. typ:=ait_real_32bit;
  471. value:=_value;
  472. end;
  473. {****************************************************************************
  474. TAI_real_64bit
  475. ****************************************************************************}
  476. constructor tai_real_64bit.Create(_value : ts64real);
  477. begin
  478. inherited Create;
  479. typ:=ait_real_64bit;
  480. value:=_value;
  481. end;
  482. {****************************************************************************
  483. TAI_real_80bit
  484. ****************************************************************************}
  485. constructor tai_real_80bit.Create(_value : ts80real);
  486. begin
  487. inherited Create;
  488. typ:=ait_real_80bit;
  489. value:=_value;
  490. end;
  491. {****************************************************************************
  492. Tai_comp_64bit
  493. ****************************************************************************}
  494. constructor tai_comp_64bit.Create(_value : ts64comp);
  495. begin
  496. inherited Create;
  497. typ:=ait_comp_64bit;
  498. value:=_value;
  499. end;
  500. {****************************************************************************
  501. TAI_STRING
  502. ****************************************************************************}
  503. constructor tai_string.Create(const _str : string);
  504. begin
  505. inherited Create;
  506. typ:=ait_string;
  507. getmem(str,length(_str)+1);
  508. strpcopy(str,_str);
  509. len:=length(_str);
  510. end;
  511. constructor tai_string.Create_pchar(_str : pchar);
  512. begin
  513. inherited Create;
  514. typ:=ait_string;
  515. str:=_str;
  516. len:=strlen(_str);
  517. end;
  518. constructor tai_string.Create_length_pchar(_str : pchar;length : longint);
  519. begin
  520. inherited Create;
  521. typ:=ait_string;
  522. str:=_str;
  523. len:=length;
  524. end;
  525. destructor tai_string.destroy;
  526. begin
  527. { you can have #0 inside the strings so }
  528. if str<>nil then
  529. freemem(str,len+1);
  530. inherited Destroy;
  531. end;
  532. {****************************************************************************
  533. TAI_LABEL
  534. ****************************************************************************}
  535. constructor tai_label.create(_l : tasmlabel);
  536. begin
  537. inherited Create;
  538. typ:=ait_label;
  539. l:=_l;
  540. l.is_set:=true;
  541. is_global:=(l.defbind=AB_GLOBAL);
  542. end;
  543. {****************************************************************************
  544. TAI_DIRECT
  545. ****************************************************************************}
  546. constructor tai_direct.Create(_str : pchar);
  547. begin
  548. inherited Create;
  549. typ:=ait_direct;
  550. str:=_str;
  551. end;
  552. destructor tai_direct.destroy;
  553. begin
  554. strdispose(str);
  555. inherited Destroy;
  556. end;
  557. {****************************************************************************
  558. TAI_ASM_COMMENT comment to be inserted in the assembler file
  559. ****************************************************************************}
  560. constructor tai_asm_comment.Create(_str : pchar);
  561. begin
  562. inherited Create;
  563. typ:=ait_comment;
  564. str:=_str;
  565. end;
  566. destructor tai_asm_comment.destroy;
  567. begin
  568. strdispose(str);
  569. inherited Destroy;
  570. end;
  571. {****************************************************************************
  572. TAI_CUT
  573. ****************************************************************************}
  574. constructor tai_cut.Create;
  575. begin
  576. inherited Create;
  577. typ:=ait_cut;
  578. place:=cut_normal;
  579. end;
  580. constructor tai_cut.Create_begin;
  581. begin
  582. inherited Create;
  583. typ:=ait_cut;
  584. place:=cut_begin;
  585. end;
  586. constructor tai_cut.Create_end;
  587. begin
  588. inherited Create;
  589. typ:=ait_cut;
  590. place:=cut_end;
  591. end;
  592. {****************************************************************************
  593. Tai_Marker
  594. ****************************************************************************}
  595. Constructor Tai_Marker.Create(_Kind: TMarker);
  596. Begin
  597. Inherited Create;
  598. typ := ait_marker;
  599. Kind := _Kind;
  600. End;
  601. {*****************************************************************************
  602. tai_tempalloc
  603. *****************************************************************************}
  604. constructor tai_tempalloc.alloc(pos,size:longint);
  605. begin
  606. inherited Create;
  607. typ:=ait_tempalloc;
  608. allocation:=true;
  609. temppos:=pos;
  610. tempsize:=size;
  611. end;
  612. constructor tai_tempalloc.dealloc(pos,size:longint);
  613. begin
  614. inherited Create;
  615. typ:=ait_tempalloc;
  616. allocation:=false;
  617. temppos:=pos;
  618. tempsize:=size;
  619. end;
  620. {*****************************************************************************
  621. tai_regalloc
  622. *****************************************************************************}
  623. constructor tai_regalloc.alloc(r : tregister);
  624. begin
  625. inherited create;
  626. typ:=ait_regalloc;
  627. allocation:=true;
  628. reg:=r;
  629. end;
  630. constructor tai_regalloc.dealloc(r : tregister);
  631. begin
  632. inherited create;
  633. typ:=ait_regalloc;
  634. allocation:=false;
  635. reg:=r;
  636. end;
  637. {*****************************************************************************
  638. TaiInstruction
  639. *****************************************************************************}
  640. constructor taicpu_abstract.Create(op : tasmop);
  641. begin
  642. inherited create;
  643. typ:=ait_instruction;
  644. is_jmp:=false;
  645. opcode:=op;
  646. ops:=0;
  647. fillchar(condition,sizeof(condition),0);
  648. fillchar(oper,sizeof(oper),0);
  649. end;
  650. destructor taicpu_abstract.Destroy;
  651. var
  652. i : longint;
  653. begin
  654. for i:=0 to ops-1 do
  655. case oper[i].typ of
  656. top_ref:
  657. dispose(oper[i].ref);
  658. top_symbol:
  659. dec(tasmsymbol(oper[i].sym).refs);
  660. end;
  661. inherited destroy;
  662. end;
  663. { ---------------------------------------------------------------------
  664. Loading of operands.
  665. ---------------------------------------------------------------------}
  666. procedure taicpu_abstract.loadconst(opidx:longint;l:aword);
  667. begin
  668. if opidx>=ops then
  669. ops:=opidx+1;
  670. with oper[opidx] do
  671. begin
  672. if typ=top_ref then
  673. dispose(ref);
  674. val:=l;
  675. typ:=top_const;
  676. end;
  677. end;
  678. procedure taicpu_abstract.loadsymbol(opidx:longint;s:tasmsymbol;sofs:longint);
  679. begin
  680. if not assigned(s) then
  681. internalerror(200204251);
  682. if opidx>=ops then
  683. ops:=opidx+1;
  684. with oper[opidx] do
  685. begin
  686. if typ=top_ref then
  687. dispose(ref);
  688. sym:=s;
  689. symofs:=sofs;
  690. typ:=top_symbol;
  691. end;
  692. inc(s.refs);
  693. end;
  694. procedure taicpu_abstract.loadref(opidx:longint;const r:treference);
  695. begin
  696. if opidx>=ops then
  697. ops:=opidx+1;
  698. with oper[opidx] do
  699. begin
  700. if typ<>top_ref then
  701. new(ref);
  702. ref^:=r;
  703. {$ifdef i386}
  704. { We allow this exception for i386, since overloading this would be
  705. too much of a a speed penalty}
  706. if not(ref^.segment in [R_DS,R_NO]) then
  707. segprefix:=ref^.segment;
  708. {$endif}
  709. typ:=top_ref;
  710. { mark symbol as used }
  711. if assigned(ref^.symbol) then
  712. inc(ref^.symbol.refs);
  713. end;
  714. end;
  715. procedure taicpu_abstract.loadreg(opidx:longint;r:tregister);
  716. begin
  717. if opidx>=ops then
  718. ops:=opidx+1;
  719. with oper[opidx] do
  720. begin
  721. if typ=top_ref then
  722. dispose(ref);
  723. reg:=r;
  724. typ:=top_reg;
  725. end;
  726. end;
  727. procedure taicpu_abstract.loadoper(opidx:longint;o:toper);
  728. begin
  729. if opidx>=ops then
  730. ops:=opidx+1;
  731. if oper[opidx].typ=top_ref then
  732. dispose(oper[opidx].ref);
  733. oper[opidx]:=o;
  734. { copy also the reference }
  735. if oper[opidx].typ=top_ref then
  736. begin
  737. new(oper[opidx].ref);
  738. oper[opidx].ref^:=o.ref^;
  739. end;
  740. end;
  741. { ---------------------------------------------------------------------
  742. Miscellaneous methods.
  743. ---------------------------------------------------------------------}
  744. procedure taicpu_abstract.SetCondition(const c:TAsmCond);
  745. begin
  746. condition:=c;
  747. end;
  748. Function taicpu_abstract.getcopy:TLinkedListItem;
  749. var
  750. i : longint;
  751. p : TLinkedListItem;
  752. begin
  753. p:=inherited getcopy;
  754. { make a copy of the references }
  755. for i:=1 to ops do
  756. if (taicpu_abstract(p).oper[i-1].typ=top_ref) then
  757. begin
  758. new(taicpu_abstract(p).oper[i-1].ref);
  759. taicpu_abstract(p).oper[i-1].ref^:=oper[i-1].ref^;
  760. end;
  761. getcopy:=p;
  762. end;
  763. {****************************************************************************
  764. tai_align_abstract
  765. ****************************************************************************}
  766. constructor tai_align_abstract.Create(b: byte);
  767. begin
  768. inherited Create;
  769. typ:=ait_align;
  770. if b in [1,2,4,8,16,32] then
  771. aligntype := b
  772. else
  773. aligntype := 1;
  774. fillsize:=0;
  775. fillop:=0;
  776. use_op:=false;
  777. end;
  778. constructor tai_align_abstract.Create_op(b: byte; _op: byte);
  779. begin
  780. inherited Create;
  781. typ:=ait_align;
  782. if b in [1,2,4,8,16,32] then
  783. aligntype := b
  784. else
  785. aligntype := 1;
  786. fillsize:=0;
  787. fillop:=_op;
  788. use_op:=true;
  789. fillchar(buf,sizeof(buf),_op)
  790. end;
  791. function tai_align_abstract.getfillbuf:pchar;
  792. begin
  793. getfillbuf:=@buf;
  794. end;
  795. {*****************************************************************************
  796. TAAsmOutput
  797. *****************************************************************************}
  798. function taasmoutput.getlasttaifilepos : pfileposinfo;
  799. begin
  800. if assigned(last) then
  801. getlasttaifilepos:=@tai(last).fileinfo
  802. else
  803. getlasttaifilepos:=nil;
  804. end;
  805. end.
  806. {
  807. $Log$
  808. Revision 1.4 2002-08-11 14:32:25 peter
  809. * renamed current_library to objectlibrary
  810. Revision 1.3 2002/08/11 13:24:10 peter
  811. * saving of asmsymbols in ppu supported
  812. * asmsymbollist global is removed and moved into a new class
  813. tasmlibrarydata that will hold the info of a .a file which
  814. corresponds with a single module. Added librarydata to tmodule
  815. to keep the library info stored for the module. In the future the
  816. objectfiles will also be stored to the tasmlibrarydata class
  817. * all getlabel/newasmsymbol and friends are moved to the new class
  818. Revision 1.2 2002/08/05 18:27:48 carl
  819. + more more more documentation
  820. + first version include/exclude (can't test though, not enough scratch for i386 :()...
  821. Revision 1.1 2002/07/01 18:46:20 peter
  822. * internal linker
  823. * reorganized aasm layer
  824. Revision 1.27 2002/05/18 13:34:04 peter
  825. * readded missing revisions
  826. Revision 1.25 2002/05/14 19:34:38 peter
  827. * removed old logs and updated copyright year
  828. Revision 1.24 2002/05/14 17:28:08 peter
  829. * synchronized cpubase between powerpc and i386
  830. * moved more tables from cpubase to cpuasm
  831. * tai_align_abstract moved to tainst, cpuasm must define
  832. the tai_align class now, which may be empty
  833. Revision 1.23 2002/04/15 18:54:34 carl
  834. - removed tcpuflags
  835. Revision 1.22 2002/04/07 13:18:19 carl
  836. + more documentation
  837. Revision 1.21 2002/04/07 10:17:40 carl
  838. - remove packenumfixed (requires version 1.0.2 or later to compile now!)
  839. + changing some comments so its commented automatically
  840. Revision 1.20 2002/03/24 19:04:31 carl
  841. + patch for SPARC from Mazen NEIFER
  842. }