aasmtai.pas 41 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491
  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. symppu,
  31. aasmbase;
  32. type
  33. tait = (
  34. ait_none,
  35. ait_direct,
  36. ait_string,
  37. ait_label,
  38. ait_comment,
  39. ait_instruction,
  40. ait_datablock,
  41. ait_symbol,
  42. ait_symbol_end, { needed to calc the size of a symbol }
  43. ait_const_32bit,
  44. ait_const_16bit,
  45. ait_const_8bit,
  46. ait_const_symbol,
  47. ait_real_80bit,
  48. ait_real_64bit,
  49. ait_real_32bit,
  50. ait_comp_64bit,
  51. ait_align,
  52. ait_section,
  53. { the following is only used by the win32 version of the compiler }
  54. { and only the GNU AS Win32 is able to write it }
  55. ait_const_rva,
  56. {$ifdef GDB}
  57. ait_stabn,
  58. ait_stabs,
  59. ait_force_line,
  60. ait_stab_function_name,
  61. {$endif GDB}
  62. ait_cut, { used to split into tiny assembler files }
  63. ait_regalloc,
  64. ait_tempalloc,
  65. ait_marker, { used to mark assembler blocks and inlined functions }
  66. {$ifdef alpha}
  67. { the follow is for the DEC Alpha }
  68. ait_frame,
  69. ait_ent,
  70. {$endif alpha}
  71. {$ifdef m68k}
  72. ait_labeled_instruction,
  73. {$endif m68k}
  74. {$ifdef ia64}
  75. ait_bundle,
  76. ait_stop,
  77. {$endif ia64}
  78. {$ifdef SPARC}
  79. ait_labeled_instruction,
  80. {$endif SPARC}
  81. { never used, makes insertation of new ait_ easier to type }
  82. { lazy guy !!!! ;-) (FK) }
  83. ait_dummy);
  84. { ait_* types which don't result in executable code or which don't influence }
  85. { the way the program runs/behaves, but which may be encountered by the }
  86. { optimizer (= if it's sometimes added to the exprasm list). Update if you add }
  87. { a new ait type! }
  88. const
  89. SkipInstr = [ait_comment, ait_symbol,ait_section
  90. {$ifdef GDB}
  91. ,ait_stabs, ait_stabn, ait_stab_function_name, ait_force_line
  92. {$endif GDB}
  93. ,ait_regalloc, ait_tempalloc, ait_symbol_end];
  94. type
  95. { cut type, required for alphanumeric ordering of the assembler filenames }
  96. TCutPlace=(cut_normal,cut_begin,cut_end);
  97. TMarker = (NoPropInfoStart,NoPropInfoEnd,
  98. AsmBlockStart,AsmBlockEnd,
  99. InlineStart,InlineEnd);
  100. { the short name makes typing easier }
  101. tai = class(TLinkedListItem)
  102. { pointer to record with optimizer info about this tai object }
  103. optinfo : pointer;
  104. fileinfo : tfileposinfo;
  105. typ : tait;
  106. constructor Create;
  107. procedure write(ppufile:tcompilerppufile);virtual;abstract;
  108. procedure derefobjectdata;virtual;
  109. end;
  110. {# Generates an assembler string }
  111. tai_string = class(tai)
  112. str : pchar;
  113. { extra len so the string can contain an \0 }
  114. len : longint;
  115. constructor Create(const _str : string);
  116. constructor Create_pchar(_str : pchar);
  117. constructor Create_length_pchar(_str : pchar;length : longint);
  118. destructor Destroy;override;
  119. constructor load(ppufile:tcompilerppufile);
  120. procedure write(ppufile:tcompilerppufile);override;
  121. end;
  122. {# Generates a common label }
  123. tai_symbol = class(tai)
  124. is_global : boolean;
  125. sym : tasmsymbol;
  126. size : longint;
  127. constructor Create(_sym:tasmsymbol;siz:longint);
  128. constructor Createname(const _name : string;siz:longint);
  129. constructor Createname_global(const _name : string;siz:longint);
  130. constructor Createdataname(const _name : string;siz:longint);
  131. constructor Createdataname_global(const _name : string;siz:longint);
  132. constructor load(ppufile:tcompilerppufile);
  133. procedure write(ppufile:tcompilerppufile);override;
  134. procedure derefobjectdata;override;
  135. end;
  136. tai_symbol_end = class(tai)
  137. sym : tasmsymbol;
  138. constructor Create(_sym:tasmsymbol);
  139. constructor Createname(const _name : string);
  140. constructor load(ppufile:tcompilerppufile);
  141. procedure write(ppufile:tcompilerppufile);override;
  142. procedure derefobjectdata;override;
  143. end;
  144. {# Generates an assembler label }
  145. tai_label = class(tai)
  146. is_global : boolean;
  147. l : tasmlabel;
  148. constructor Create(_l : tasmlabel);
  149. constructor load(ppufile:tcompilerppufile);
  150. procedure write(ppufile:tcompilerppufile);override;
  151. procedure derefobjectdata;override;
  152. end;
  153. {# Directly output data to final assembler file }
  154. tai_direct = class(tai)
  155. str : pchar;
  156. constructor Create(_str : pchar);
  157. destructor Destroy; override;
  158. constructor load(ppufile:tcompilerppufile);
  159. procedure write(ppufile:tcompilerppufile);override;
  160. end;
  161. {# Generates an assembler comment }
  162. tai_asm_comment = class(tai)
  163. str : pchar;
  164. constructor Create(_str : pchar);
  165. destructor Destroy; override;
  166. constructor load(ppufile:tcompilerppufile);
  167. procedure write(ppufile:tcompilerppufile);override;
  168. end;
  169. {# Generates a section / segment directive }
  170. tai_section = class(tai)
  171. sec : TSection;
  172. constructor Create(s : TSection);
  173. constructor load(ppufile:tcompilerppufile);
  174. procedure write(ppufile:tcompilerppufile);override;
  175. end;
  176. {# Generates an uninitializised data block }
  177. tai_datablock = class(tai)
  178. is_global : boolean;
  179. sym : tasmsymbol;
  180. size : longint;
  181. constructor Create(const _name : string;_size : longint);
  182. constructor Create_global(const _name : string;_size : longint);
  183. constructor load(ppufile:tcompilerppufile);
  184. procedure write(ppufile:tcompilerppufile);override;
  185. procedure derefobjectdata;override;
  186. end;
  187. {# Generates a long integer (32 bit) }
  188. tai_const = class(tai)
  189. value : longint;
  190. constructor Create_32bit(_value : longint);
  191. constructor Create_16bit(_value : word);
  192. constructor Create_8bit(_value : byte);
  193. constructor load(ppufile:tcompilerppufile);
  194. procedure write(ppufile:tcompilerppufile);override;
  195. end;
  196. tai_const_symbol = class(tai)
  197. sym : tasmsymbol;
  198. offset : longint;
  199. constructor Create(_sym:tasmsymbol);
  200. constructor Create_offset(_sym:tasmsymbol;ofs:longint);
  201. constructor Create_rva(_sym:tasmsymbol);
  202. constructor Createname(const name:string);
  203. constructor Createname_offset(const name:string;ofs:longint);
  204. constructor Createname_rva(const name:string);
  205. constructor load(ppufile:tcompilerppufile);
  206. procedure write(ppufile:tcompilerppufile);override;
  207. procedure derefobjectdata;override;
  208. end;
  209. {# Generates a single float (32 bit real) }
  210. tai_real_32bit = class(tai)
  211. value : ts32real;
  212. constructor Create(_value : ts32real);
  213. constructor load(ppufile:tcompilerppufile);
  214. procedure write(ppufile:tcompilerppufile);override;
  215. end;
  216. {# Generates a double float (64 bit real) }
  217. tai_real_64bit = class(tai)
  218. value : ts64real;
  219. constructor Create(_value : ts64real);
  220. constructor load(ppufile:tcompilerppufile);
  221. procedure write(ppufile:tcompilerppufile);override;
  222. end;
  223. {# Generates an extended float (80 bit real) }
  224. tai_real_80bit = class(tai)
  225. value : ts80real;
  226. constructor Create(_value : ts80real);
  227. constructor load(ppufile:tcompilerppufile);
  228. procedure write(ppufile:tcompilerppufile);override;
  229. end;
  230. {# Generates a comp int (integer over 64 bits)
  231. This is Intel 80x86 specific, and is not
  232. really supported on other processors.
  233. }
  234. tai_comp_64bit = class(tai)
  235. value : ts64comp;
  236. constructor Create(_value : ts64comp);
  237. constructor load(ppufile:tcompilerppufile);
  238. procedure write(ppufile:tcompilerppufile);override;
  239. end;
  240. {# Insert a cut to split assembler into several smaller files }
  241. tai_cut = class(tai)
  242. place : tcutplace;
  243. constructor Create;
  244. constructor Create_begin;
  245. constructor Create_end;
  246. constructor load(ppufile:tcompilerppufile);
  247. procedure write(ppufile:tcompilerppufile);override;
  248. end;
  249. {# Insert a marker for assembler and inline blocks }
  250. tai_marker = class(tai)
  251. Kind: TMarker;
  252. Constructor Create(_Kind: TMarker);
  253. constructor load(ppufile:tcompilerppufile);
  254. procedure write(ppufile:tcompilerppufile);override;
  255. end;
  256. tai_tempalloc = class(tai)
  257. allocation : boolean;
  258. temppos,
  259. tempsize : longint;
  260. constructor alloc(pos,size:longint);
  261. constructor dealloc(pos,size:longint);
  262. constructor load(ppufile:tcompilerppufile);
  263. procedure write(ppufile:tcompilerppufile);override;
  264. end;
  265. tai_regalloc = class(tai)
  266. allocation : boolean;
  267. reg : tregister;
  268. constructor alloc(r : tregister);
  269. constructor dealloc(r : tregister);
  270. constructor load(ppufile:tcompilerppufile);
  271. procedure write(ppufile:tcompilerppufile);override;
  272. end;
  273. {# Class template for assembler instructions
  274. }
  275. taicpu_abstract = class(tai)
  276. protected
  277. procedure ppuloadoper(ppufile:tcompilerppufile;var o:toper);virtual;abstract;
  278. procedure ppuwriteoper(ppufile:tcompilerppufile;const o:toper);virtual;abstract;
  279. procedure ppuderefoper(var o:toper);virtual;abstract;
  280. public
  281. {# Condition flags for instruction }
  282. condition : TAsmCond;
  283. {# Number of operands to instruction }
  284. ops : byte;
  285. {# Operands of instruction }
  286. oper : array[0..max_operands-1] of toper;
  287. {# Actual opcode of instruction }
  288. opcode : tasmop;
  289. {$ifdef i386}
  290. segprefix : tregister;
  291. {$endif i386}
  292. {# true if instruction is a jmp }
  293. is_jmp : boolean; { is this instruction a jump? (needed for optimizer) }
  294. Constructor Create(op : tasmop);
  295. Destructor Destroy;override;
  296. function getcopy:TLinkedListItem;override;
  297. constructor load(ppufile:tcompilerppufile);
  298. procedure write(ppufile:tcompilerppufile);override;
  299. procedure derefobjectdata;override;
  300. procedure SetCondition(const c:TAsmCond);
  301. procedure loadconst(opidx:longint;l:aword);
  302. procedure loadsymbol(opidx:longint;s:tasmsymbol;sofs:longint);
  303. procedure loadref(opidx:longint;const r:treference);
  304. procedure loadreg(opidx:longint;r:tregister);
  305. procedure loadoper(opidx:longint;o:toper);
  306. end;
  307. {# alignment for operator }
  308. tai_align_abstract = class(tai)
  309. buf : array[0..63] of char; { buf used for fill }
  310. aligntype : byte; { 1 = no align, 2 = word align, 4 = dword align }
  311. fillsize : byte; { real size to fill }
  312. fillop : byte; { value to fill with - optional }
  313. use_op : boolean;
  314. constructor Create(b:byte);
  315. constructor Create_op(b: byte; _op: byte);
  316. constructor load(ppufile:tcompilerppufile);
  317. procedure write(ppufile:tcompilerppufile);override;
  318. function getfillbuf:pchar;virtual;
  319. end;
  320. taasmoutput = class(tlinkedlist)
  321. function getlasttaifilepos : pfileposinfo;
  322. end;
  323. var
  324. { temporary lists }
  325. exprasmlist,
  326. { default lists }
  327. datasegment,codesegment,bsssegment,
  328. debuglist,withdebuglist,consts,
  329. importssection,exportssection,
  330. resourcesection,rttilist,
  331. resourcestringlist : taasmoutput;
  332. implementation
  333. uses
  334. {$ifdef delphi}
  335. sysutils,
  336. {$else}
  337. strings,
  338. {$endif}
  339. verbose,
  340. ppu;
  341. {****************************************************************************
  342. TAI
  343. ****************************************************************************}
  344. constructor tai.Create;
  345. begin
  346. optinfo := nil;
  347. fileinfo:=aktfilepos;
  348. end;
  349. procedure tai.derefobjectdata;
  350. begin
  351. end;
  352. {****************************************************************************
  353. TAI_SECTION
  354. ****************************************************************************}
  355. constructor tai_section.Create(s : TSection);
  356. begin
  357. inherited Create;
  358. typ:=ait_section;
  359. sec:=s;
  360. end;
  361. constructor tai_section.load(ppufile:tcompilerppufile);
  362. begin
  363. inherited Create;
  364. sec:=tsection(ppufile.getbyte);
  365. end;
  366. procedure tai_section.write(ppufile:tcompilerppufile);
  367. begin
  368. ppufile.putbyte(byte(sec));
  369. ppufile.writeentry(ibtaisection);
  370. end;
  371. {****************************************************************************
  372. TAI_DATABLOCK
  373. ****************************************************************************}
  374. constructor tai_datablock.Create(const _name : string;_size : longint);
  375. begin
  376. inherited Create;
  377. typ:=ait_datablock;
  378. sym:=objectlibrary.newasmsymboltype(_name,AB_LOCAL,AT_DATA);
  379. { keep things aligned }
  380. if _size<=0 then
  381. _size:=4;
  382. size:=_size;
  383. is_global:=false;
  384. end;
  385. constructor tai_datablock.Create_global(const _name : string;_size : longint);
  386. begin
  387. inherited Create;
  388. typ:=ait_datablock;
  389. sym:=objectlibrary.newasmsymboltype(_name,AB_GLOBAL,AT_DATA);
  390. { keep things aligned }
  391. if _size<=0 then
  392. _size:=4;
  393. size:=_size;
  394. is_global:=true;
  395. end;
  396. constructor tai_datablock.load(ppufile:tcompilerppufile);
  397. begin
  398. inherited Create;
  399. sym:=ppufile.getasmsymbol;
  400. size:=ppufile.getlongint;
  401. is_global:=boolean(ppufile.getbyte);
  402. end;
  403. procedure tai_datablock.write(ppufile:tcompilerppufile);
  404. begin
  405. ppufile.putasmsymbol(sym);
  406. ppufile.putlongint(size);
  407. ppufile.putbyte(byte(is_global));
  408. ppufile.writeentry(ibtaidatablock);
  409. end;
  410. procedure tai_datablock.derefobjectdata;
  411. begin
  412. objectlibrary.DerefAsmsymbol(sym);
  413. end;
  414. {****************************************************************************
  415. TAI_SYMBOL
  416. ****************************************************************************}
  417. constructor tai_symbol.Create(_sym:tasmsymbol;siz:longint);
  418. begin
  419. inherited Create;
  420. typ:=ait_symbol;
  421. sym:=_sym;
  422. size:=siz;
  423. is_global:=(sym.defbind=AB_GLOBAL);
  424. end;
  425. constructor tai_symbol.Createname(const _name : string;siz:longint);
  426. begin
  427. inherited Create;
  428. typ:=ait_symbol;
  429. sym:=objectlibrary.newasmsymboltype(_name,AB_LOCAL,AT_FUNCTION);
  430. size:=siz;
  431. is_global:=false;
  432. end;
  433. constructor tai_symbol.Createname_global(const _name : string;siz:longint);
  434. begin
  435. inherited Create;
  436. typ:=ait_symbol;
  437. sym:=objectlibrary.newasmsymboltype(_name,AB_GLOBAL,AT_FUNCTION);
  438. size:=siz;
  439. is_global:=true;
  440. end;
  441. constructor tai_symbol.Createdataname(const _name : string;siz:longint);
  442. begin
  443. inherited Create;
  444. typ:=ait_symbol;
  445. sym:=objectlibrary.newasmsymboltype(_name,AB_LOCAL,AT_DATA);
  446. size:=siz;
  447. is_global:=false;
  448. end;
  449. constructor tai_symbol.Createdataname_global(const _name : string;siz:longint);
  450. begin
  451. inherited Create;
  452. typ:=ait_symbol;
  453. sym:=objectlibrary.newasmsymboltype(_name,AB_GLOBAL,AT_DATA);
  454. size:=siz;
  455. is_global:=true;
  456. end;
  457. constructor tai_symbol.load(ppufile:tcompilerppufile);
  458. begin
  459. inherited Create;
  460. sym:=ppufile.getasmsymbol;
  461. size:=ppufile.getlongint;
  462. is_global:=boolean(ppufile.getbyte);
  463. end;
  464. procedure tai_symbol.write(ppufile:tcompilerppufile);
  465. begin
  466. ppufile.putasmsymbol(sym);
  467. ppufile.putlongint(size);
  468. ppufile.putbyte(byte(is_global));
  469. ppufile.writeentry(ibtaisymbol);
  470. end;
  471. procedure tai_symbol.derefobjectdata;
  472. begin
  473. objectlibrary.DerefAsmsymbol(sym);
  474. end;
  475. {****************************************************************************
  476. TAI_SYMBOL
  477. ****************************************************************************}
  478. constructor tai_symbol_end.Create(_sym:tasmsymbol);
  479. begin
  480. inherited Create;
  481. typ:=ait_symbol_end;
  482. sym:=_sym;
  483. end;
  484. constructor tai_symbol_end.Createname(const _name : string);
  485. begin
  486. inherited Create;
  487. typ:=ait_symbol_end;
  488. sym:=objectlibrary.newasmsymboltype(_name,AB_GLOBAL,AT_NONE);
  489. end;
  490. constructor tai_symbol_end.load(ppufile:tcompilerppufile);
  491. begin
  492. inherited Create;
  493. sym:=ppufile.getasmsymbol;
  494. end;
  495. procedure tai_symbol_end.write(ppufile:tcompilerppufile);
  496. begin
  497. ppufile.putasmsymbol(sym);
  498. ppufile.writeentry(ibtaisymbol);
  499. end;
  500. procedure tai_symbol_end.derefobjectdata;
  501. begin
  502. objectlibrary.DerefAsmsymbol(sym);
  503. end;
  504. {****************************************************************************
  505. TAI_CONST
  506. ****************************************************************************}
  507. constructor tai_const.Create_32bit(_value : longint);
  508. begin
  509. inherited Create;
  510. typ:=ait_const_32bit;
  511. value:=_value;
  512. end;
  513. constructor tai_const.Create_16bit(_value : word);
  514. begin
  515. inherited Create;
  516. typ:=ait_const_16bit;
  517. value:=_value;
  518. end;
  519. constructor tai_const.Create_8bit(_value : byte);
  520. begin
  521. inherited Create;
  522. typ:=ait_const_8bit;
  523. value:=_value;
  524. end;
  525. constructor tai_const.load(ppufile:tcompilerppufile);
  526. begin
  527. inherited Create;
  528. value:=ppufile.getlongint;
  529. end;
  530. procedure tai_const.write(ppufile:tcompilerppufile);
  531. begin
  532. ppufile.putlongint(value);
  533. case typ of
  534. ait_const_8bit :
  535. ppufile.writeentry(ibtaiconst_8bit);
  536. ait_const_16bit :
  537. ppufile.writeentry(ibtaiconst_16bit);
  538. ait_const_32bit :
  539. ppufile.writeentry(ibtaiconst_32bit);
  540. end;
  541. end;
  542. {****************************************************************************
  543. TAI_CONST_SYMBOL_OFFSET
  544. ****************************************************************************}
  545. constructor tai_const_symbol.Create(_sym:tasmsymbol);
  546. begin
  547. inherited Create;
  548. typ:=ait_const_symbol;
  549. sym:=_sym;
  550. offset:=0;
  551. { update sym info }
  552. inc(sym.refs);
  553. end;
  554. constructor tai_const_symbol.Create_offset(_sym:tasmsymbol;ofs:longint);
  555. begin
  556. inherited Create;
  557. typ:=ait_const_symbol;
  558. sym:=_sym;
  559. offset:=ofs;
  560. { update sym info }
  561. inc(sym.refs);
  562. end;
  563. constructor tai_const_symbol.Create_rva(_sym:tasmsymbol);
  564. begin
  565. inherited Create;
  566. typ:=ait_const_rva;
  567. sym:=_sym;
  568. offset:=0;
  569. { update sym info }
  570. inc(sym.refs);
  571. end;
  572. constructor tai_const_symbol.Createname(const name:string);
  573. begin
  574. inherited Create;
  575. typ:=ait_const_symbol;
  576. sym:=objectlibrary.newasmsymbol(name);
  577. offset:=0;
  578. { update sym info }
  579. inc(sym.refs);
  580. end;
  581. constructor tai_const_symbol.Createname_offset(const name:string;ofs:longint);
  582. begin
  583. inherited Create;
  584. typ:=ait_const_symbol;
  585. sym:=objectlibrary.newasmsymbol(name);
  586. offset:=ofs;
  587. { update sym info }
  588. inc(sym.refs);
  589. end;
  590. constructor tai_const_symbol.Createname_rva(const name:string);
  591. begin
  592. inherited Create;
  593. typ:=ait_const_rva;
  594. sym:=objectlibrary.newasmsymbol(name);
  595. offset:=0;
  596. { update sym info }
  597. inc(sym.refs);
  598. end;
  599. constructor tai_const_symbol.load(ppufile:tcompilerppufile);
  600. begin
  601. inherited Create;
  602. sym:=ppufile.getasmsymbol;
  603. offset:=ppufile.getlongint;
  604. end;
  605. procedure tai_const_symbol.write(ppufile:tcompilerppufile);
  606. begin
  607. ppufile.putasmsymbol(sym);
  608. ppufile.putlongint(offset);
  609. case typ of
  610. ait_const_symbol :
  611. ppufile.writeentry(ibtaiconst_symbol);
  612. ait_const_rva :
  613. ppufile.writeentry(ibtaiconst_rva);
  614. end;
  615. end;
  616. procedure tai_const_symbol.derefobjectdata;
  617. begin
  618. objectlibrary.DerefAsmsymbol(sym);
  619. end;
  620. {****************************************************************************
  621. TAI_real_32bit
  622. ****************************************************************************}
  623. constructor tai_real_32bit.Create(_value : ts32real);
  624. begin
  625. inherited Create;
  626. typ:=ait_real_32bit;
  627. value:=_value;
  628. end;
  629. constructor tai_real_32bit.load(ppufile:tcompilerppufile);
  630. begin
  631. inherited Create;
  632. value:=ppufile.getreal;
  633. end;
  634. procedure tai_real_32bit.write(ppufile:tcompilerppufile);
  635. begin
  636. ppufile.putreal(value);
  637. ppufile.writeentry(ibtaireal_32bit);
  638. end;
  639. {****************************************************************************
  640. TAI_real_64bit
  641. ****************************************************************************}
  642. constructor tai_real_64bit.Create(_value : ts64real);
  643. begin
  644. inherited Create;
  645. typ:=ait_real_64bit;
  646. value:=_value;
  647. end;
  648. constructor tai_real_64bit.load(ppufile:tcompilerppufile);
  649. begin
  650. inherited Create;
  651. value:=ppufile.getreal;
  652. end;
  653. procedure tai_real_64bit.write(ppufile:tcompilerppufile);
  654. begin
  655. ppufile.putreal(value);
  656. ppufile.writeentry(ibtaireal_64bit);
  657. end;
  658. {****************************************************************************
  659. TAI_real_80bit
  660. ****************************************************************************}
  661. constructor tai_real_80bit.Create(_value : ts80real);
  662. begin
  663. inherited Create;
  664. typ:=ait_real_80bit;
  665. value:=_value;
  666. end;
  667. constructor tai_real_80bit.load(ppufile:tcompilerppufile);
  668. begin
  669. inherited Create;
  670. value:=ppufile.getreal;
  671. end;
  672. procedure tai_real_80bit.write(ppufile:tcompilerppufile);
  673. begin
  674. ppufile.putreal(value);
  675. ppufile.writeentry(ibtaireal_80bit);
  676. end;
  677. {****************************************************************************
  678. Tai_comp_64bit
  679. ****************************************************************************}
  680. constructor tai_comp_64bit.Create(_value : ts64comp);
  681. begin
  682. inherited Create;
  683. typ:=ait_comp_64bit;
  684. value:=_value;
  685. end;
  686. constructor tai_comp_64bit.load(ppufile:tcompilerppufile);
  687. begin
  688. inherited Create;
  689. value:=ppufile.getreal;
  690. end;
  691. procedure tai_comp_64bit.write(ppufile:tcompilerppufile);
  692. begin
  693. ppufile.putreal(value);
  694. ppufile.writeentry(ibtaicomp_64bit);
  695. end;
  696. {****************************************************************************
  697. TAI_STRING
  698. ****************************************************************************}
  699. constructor tai_string.Create(const _str : string);
  700. begin
  701. inherited Create;
  702. typ:=ait_string;
  703. len:=length(_str);
  704. getmem(str,len+1);
  705. strpcopy(str,_str);
  706. end;
  707. constructor tai_string.Create_pchar(_str : pchar);
  708. begin
  709. inherited Create;
  710. typ:=ait_string;
  711. str:=_str;
  712. len:=strlen(_str);
  713. end;
  714. constructor tai_string.Create_length_pchar(_str : pchar;length : longint);
  715. begin
  716. inherited Create;
  717. typ:=ait_string;
  718. str:=_str;
  719. len:=length;
  720. end;
  721. destructor tai_string.destroy;
  722. begin
  723. { you can have #0 inside the strings so }
  724. if str<>nil then
  725. freemem(str,len+1);
  726. inherited Destroy;
  727. end;
  728. constructor tai_string.load(ppufile:tcompilerppufile);
  729. begin
  730. inherited Create;
  731. len:=ppufile.getlongint;
  732. getmem(str,len+1);
  733. ppufile.getdata(str^,len);
  734. str[len]:=#0;
  735. end;
  736. procedure tai_string.write(ppufile:tcompilerppufile);
  737. begin
  738. ppufile.putlongint(len);
  739. ppufile.putdata(str^,len);
  740. ppufile.writeentry(ibtaistring);
  741. end;
  742. {****************************************************************************
  743. TAI_LABEL
  744. ****************************************************************************}
  745. constructor tai_label.create(_l : tasmlabel);
  746. begin
  747. inherited Create;
  748. typ:=ait_label;
  749. l:=_l;
  750. l.is_set:=true;
  751. is_global:=(l.defbind=AB_GLOBAL);
  752. end;
  753. constructor tai_label.load(ppufile:tcompilerppufile);
  754. begin
  755. inherited Create;
  756. l:=tasmlabel(ppufile.getasmsymbol);
  757. l.is_set:=true;
  758. is_global:=boolean(ppufile.getbyte);
  759. end;
  760. procedure tai_label.write(ppufile:tcompilerppufile);
  761. begin
  762. ppufile.putasmsymbol(l);
  763. ppufile.putbyte(byte(is_global));
  764. ppufile.writeentry(ibtailabel);
  765. end;
  766. procedure tai_label.derefobjectdata;
  767. begin
  768. objectlibrary.DerefAsmsymbol(l);
  769. end;
  770. {****************************************************************************
  771. TAI_DIRECT
  772. ****************************************************************************}
  773. constructor tai_direct.Create(_str : pchar);
  774. begin
  775. inherited Create;
  776. typ:=ait_direct;
  777. str:=_str;
  778. end;
  779. destructor tai_direct.destroy;
  780. begin
  781. strdispose(str);
  782. inherited Destroy;
  783. end;
  784. constructor tai_direct.load(ppufile:tcompilerppufile);
  785. var
  786. len : longint;
  787. begin
  788. inherited Create;
  789. len:=ppufile.getlongint;
  790. getmem(str,len+1);
  791. ppufile.getdata(str^,len);
  792. str[len]:=#0;
  793. end;
  794. procedure tai_direct.write(ppufile:tcompilerppufile);
  795. var
  796. len : longint;
  797. begin
  798. len:=strlen(str);
  799. ppufile.putlongint(len);
  800. ppufile.putdata(str^,len);
  801. ppufile.writeentry(ibtaidirect);
  802. end;
  803. {****************************************************************************
  804. TAI_ASM_COMMENT comment to be inserted in the assembler file
  805. ****************************************************************************}
  806. constructor tai_asm_comment.Create(_str : pchar);
  807. begin
  808. inherited Create;
  809. typ:=ait_comment;
  810. str:=_str;
  811. end;
  812. destructor tai_asm_comment.destroy;
  813. begin
  814. strdispose(str);
  815. inherited Destroy;
  816. end;
  817. constructor tai_asm_comment.load(ppufile:tcompilerppufile);
  818. var
  819. len : longint;
  820. begin
  821. inherited Create;
  822. len:=ppufile.getlongint;
  823. getmem(str,len+1);
  824. ppufile.getdata(str^,len);
  825. str[len]:=#0;
  826. end;
  827. procedure tai_asm_comment.write(ppufile:tcompilerppufile);
  828. var
  829. len : longint;
  830. begin
  831. len:=strlen(str);
  832. ppufile.putlongint(len);
  833. ppufile.putdata(str^,len);
  834. ppufile.writeentry(ibtaicomment);
  835. end;
  836. {****************************************************************************
  837. TAI_CUT
  838. ****************************************************************************}
  839. constructor tai_cut.Create;
  840. begin
  841. inherited Create;
  842. typ:=ait_cut;
  843. place:=cut_normal;
  844. end;
  845. constructor tai_cut.Create_begin;
  846. begin
  847. inherited Create;
  848. typ:=ait_cut;
  849. place:=cut_begin;
  850. end;
  851. constructor tai_cut.Create_end;
  852. begin
  853. inherited Create;
  854. typ:=ait_cut;
  855. place:=cut_end;
  856. end;
  857. constructor tai_cut.load(ppufile:tcompilerppufile);
  858. begin
  859. inherited Create;
  860. place:=TCutPlace(ppufile.getbyte);
  861. end;
  862. procedure tai_cut.write(ppufile:tcompilerppufile);
  863. begin
  864. ppufile.putbyte(byte(place));
  865. ppufile.writeentry(ibtaicut);
  866. end;
  867. {****************************************************************************
  868. Tai_Marker
  869. ****************************************************************************}
  870. Constructor Tai_Marker.Create(_Kind: TMarker);
  871. Begin
  872. Inherited Create;
  873. typ := ait_marker;
  874. Kind := _Kind;
  875. End;
  876. constructor Tai_Marker.load(ppufile:tcompilerppufile);
  877. begin
  878. inherited Create;
  879. kind:=TMarker(ppufile.getbyte);
  880. end;
  881. procedure Tai_Marker.write(ppufile:tcompilerppufile);
  882. begin
  883. ppufile.putbyte(byte(kind));
  884. ppufile.writeentry(ibtaimarker);
  885. end;
  886. {*****************************************************************************
  887. tai_tempalloc
  888. *****************************************************************************}
  889. constructor tai_tempalloc.alloc(pos,size:longint);
  890. begin
  891. inherited Create;
  892. typ:=ait_tempalloc;
  893. allocation:=true;
  894. temppos:=pos;
  895. tempsize:=size;
  896. end;
  897. constructor tai_tempalloc.dealloc(pos,size:longint);
  898. begin
  899. inherited Create;
  900. typ:=ait_tempalloc;
  901. allocation:=false;
  902. temppos:=pos;
  903. tempsize:=size;
  904. end;
  905. constructor tai_tempalloc.load(ppufile:tcompilerppufile);
  906. begin
  907. inherited Create;
  908. temppos:=ppufile.getlongint;
  909. tempsize:=ppufile.getlongint;
  910. allocation:=boolean(ppufile.getbyte);
  911. end;
  912. procedure tai_tempalloc.write(ppufile:tcompilerppufile);
  913. begin
  914. ppufile.putlongint(temppos);
  915. ppufile.putlongint(tempsize);
  916. ppufile.putbyte(byte(allocation));
  917. ppufile.writeentry(ibtaitempalloc);
  918. end;
  919. {*****************************************************************************
  920. tai_regalloc
  921. *****************************************************************************}
  922. constructor tai_regalloc.alloc(r : tregister);
  923. begin
  924. inherited create;
  925. typ:=ait_regalloc;
  926. allocation:=true;
  927. reg:=r;
  928. end;
  929. constructor tai_regalloc.dealloc(r : tregister);
  930. begin
  931. inherited create;
  932. typ:=ait_regalloc;
  933. allocation:=false;
  934. reg:=r;
  935. end;
  936. constructor tai_regalloc.load(ppufile:tcompilerppufile);
  937. begin
  938. inherited Create;
  939. reg:=tregister(ppufile.getbyte);
  940. allocation:=boolean(ppufile.getbyte);
  941. end;
  942. procedure tai_regalloc.write(ppufile:tcompilerppufile);
  943. begin
  944. ppufile.putbyte(byte(reg));
  945. ppufile.putbyte(byte(allocation));
  946. ppufile.writeentry(ibtairegalloc);
  947. end;
  948. {*****************************************************************************
  949. TaiInstruction
  950. *****************************************************************************}
  951. constructor taicpu_abstract.Create(op : tasmop);
  952. begin
  953. inherited create;
  954. typ:=ait_instruction;
  955. is_jmp:=false;
  956. opcode:=op;
  957. ops:=0;
  958. fillchar(condition,sizeof(condition),0);
  959. fillchar(oper,sizeof(oper),0);
  960. end;
  961. destructor taicpu_abstract.Destroy;
  962. var
  963. i : longint;
  964. begin
  965. for i:=0 to ops-1 do
  966. case oper[i].typ of
  967. top_ref:
  968. dispose(oper[i].ref);
  969. top_symbol:
  970. dec(tasmsymbol(oper[i].sym).refs);
  971. end;
  972. inherited destroy;
  973. end;
  974. { ---------------------------------------------------------------------
  975. Loading of operands.
  976. ---------------------------------------------------------------------}
  977. procedure taicpu_abstract.loadconst(opidx:longint;l:aword);
  978. begin
  979. if opidx>=ops then
  980. ops:=opidx+1;
  981. with oper[opidx] do
  982. begin
  983. if typ=top_ref then
  984. dispose(ref);
  985. val:=l;
  986. typ:=top_const;
  987. end;
  988. end;
  989. procedure taicpu_abstract.loadsymbol(opidx:longint;s:tasmsymbol;sofs:longint);
  990. begin
  991. if not assigned(s) then
  992. internalerror(200204251);
  993. if opidx>=ops then
  994. ops:=opidx+1;
  995. with oper[opidx] do
  996. begin
  997. if typ=top_ref then
  998. dispose(ref);
  999. sym:=s;
  1000. symofs:=sofs;
  1001. typ:=top_symbol;
  1002. end;
  1003. inc(s.refs);
  1004. end;
  1005. procedure taicpu_abstract.loadref(opidx:longint;const r:treference);
  1006. begin
  1007. if opidx>=ops then
  1008. ops:=opidx+1;
  1009. with oper[opidx] do
  1010. begin
  1011. if typ<>top_ref then
  1012. new(ref);
  1013. ref^:=r;
  1014. {$ifdef i386}
  1015. { We allow this exception for i386, since overloading this would be
  1016. too much of a a speed penalty}
  1017. if not(ref^.segment in [R_DS,R_NO]) then
  1018. segprefix:=ref^.segment;
  1019. {$endif}
  1020. typ:=top_ref;
  1021. { mark symbol as used }
  1022. if assigned(ref^.symbol) then
  1023. inc(ref^.symbol.refs);
  1024. end;
  1025. end;
  1026. procedure taicpu_abstract.loadreg(opidx:longint;r:tregister);
  1027. begin
  1028. if opidx>=ops then
  1029. ops:=opidx+1;
  1030. with oper[opidx] do
  1031. begin
  1032. if typ=top_ref then
  1033. dispose(ref);
  1034. reg:=r;
  1035. typ:=top_reg;
  1036. end;
  1037. end;
  1038. procedure taicpu_abstract.loadoper(opidx:longint;o:toper);
  1039. begin
  1040. if opidx>=ops then
  1041. ops:=opidx+1;
  1042. if oper[opidx].typ=top_ref then
  1043. dispose(oper[opidx].ref);
  1044. oper[opidx]:=o;
  1045. { copy also the reference }
  1046. if oper[opidx].typ=top_ref then
  1047. begin
  1048. new(oper[opidx].ref);
  1049. oper[opidx].ref^:=o.ref^;
  1050. end;
  1051. end;
  1052. { ---------------------------------------------------------------------
  1053. Miscellaneous methods.
  1054. ---------------------------------------------------------------------}
  1055. procedure taicpu_abstract.SetCondition(const c:TAsmCond);
  1056. begin
  1057. condition:=c;
  1058. end;
  1059. Function taicpu_abstract.getcopy:TLinkedListItem;
  1060. var
  1061. i : longint;
  1062. p : TLinkedListItem;
  1063. begin
  1064. p:=inherited getcopy;
  1065. { make a copy of the references }
  1066. for i:=1 to ops do
  1067. if (taicpu_abstract(p).oper[i-1].typ=top_ref) then
  1068. begin
  1069. new(taicpu_abstract(p).oper[i-1].ref);
  1070. taicpu_abstract(p).oper[i-1].ref^:=oper[i-1].ref^;
  1071. end;
  1072. getcopy:=p;
  1073. end;
  1074. constructor taicpu_abstract.load(ppufile:tcompilerppufile);
  1075. var
  1076. i : integer;
  1077. begin
  1078. inherited Create;
  1079. { hopefully, we don't get problems with big/litte endian here when cross compiling :/ }
  1080. ppufile.getdata(condition,sizeof(tasmcond));
  1081. ops:=ppufile.getbyte;
  1082. for i:=1 to ops do
  1083. ppuloadoper(ppufile,oper[i-1]);
  1084. opcode:=tasmop(ppufile.getword);
  1085. {$ifdef i386}
  1086. segprefix:=tregister(ppufile.getbyte);
  1087. {$endif i386}
  1088. is_jmp:=boolean(ppufile.getbyte);
  1089. end;
  1090. procedure taicpu_abstract.write(ppufile:tcompilerppufile);
  1091. var
  1092. i : integer;
  1093. begin
  1094. ppufile.putdata(condition,sizeof(tasmcond));
  1095. ppufile.putbyte(ops);
  1096. for i:=1 to ops do
  1097. ppuwriteoper(ppufile,oper[i-1]);
  1098. ppufile.putword(word(opcode));
  1099. {$ifdef i386}
  1100. ppufile.putbyte(byte(segprefix));
  1101. {$endif i386}
  1102. ppufile.writeentry(ibtaiinstruction);
  1103. end;
  1104. procedure taicpu_abstract.derefobjectdata;
  1105. var
  1106. i : integer;
  1107. begin
  1108. for i:=1 to ops do
  1109. ppuderefoper(oper[i-1]);
  1110. end;
  1111. {****************************************************************************
  1112. tai_align_abstract
  1113. ****************************************************************************}
  1114. constructor tai_align_abstract.Create(b: byte);
  1115. begin
  1116. inherited Create;
  1117. typ:=ait_align;
  1118. if b in [1,2,4,8,16,32] then
  1119. aligntype := b
  1120. else
  1121. aligntype := 1;
  1122. fillsize:=0;
  1123. fillop:=0;
  1124. use_op:=false;
  1125. end;
  1126. constructor tai_align_abstract.Create_op(b: byte; _op: byte);
  1127. begin
  1128. inherited Create;
  1129. typ:=ait_align;
  1130. if b in [1,2,4,8,16,32] then
  1131. aligntype := b
  1132. else
  1133. aligntype := 1;
  1134. fillsize:=0;
  1135. fillop:=_op;
  1136. use_op:=true;
  1137. fillchar(buf,sizeof(buf),_op)
  1138. end;
  1139. function tai_align_abstract.getfillbuf:pchar;
  1140. begin
  1141. getfillbuf:=@buf;
  1142. end;
  1143. constructor tai_align_abstract.load(ppufile:tcompilerppufile);
  1144. begin
  1145. inherited Create;
  1146. aligntype:=ppufile.getbyte;
  1147. fillsize:=0;
  1148. fillop:=ppufile.getbyte;
  1149. use_op:=boolean(ppufile.getbyte);
  1150. end;
  1151. procedure tai_align_abstract.write(ppufile:tcompilerppufile);
  1152. begin
  1153. ppufile.putbyte(aligntype);
  1154. ppufile.putbyte(fillop);
  1155. ppufile.putbyte(byte(use_op));
  1156. ppufile.writeentry(ibtaialign);
  1157. end;
  1158. {*****************************************************************************
  1159. TAAsmOutput
  1160. *****************************************************************************}
  1161. function taasmoutput.getlasttaifilepos : pfileposinfo;
  1162. begin
  1163. if assigned(last) then
  1164. getlasttaifilepos:=@tai(last).fileinfo
  1165. else
  1166. getlasttaifilepos:=nil;
  1167. end;
  1168. end.
  1169. {
  1170. $Log$
  1171. Revision 1.6 2002-08-16 05:21:09 florian
  1172. * powerpc compilation fix
  1173. Revision 1.5 2002/08/15 19:10:35 peter
  1174. * first things tai,tnode storing in ppu
  1175. Revision 1.4 2002/08/11 14:32:25 peter
  1176. * renamed current_library to objectlibrary
  1177. Revision 1.3 2002/08/11 13:24:10 peter
  1178. * saving of asmsymbols in ppu supported
  1179. * asmsymbollist global is removed and moved into a new class
  1180. tasmlibrarydata that will hold the info of a .a file which
  1181. corresponds with a single module. Added librarydata to tmodule
  1182. to keep the library info stored for the module. In the future the
  1183. objectfiles will also be stored to the tasmlibrarydata class
  1184. * all getlabel/newasmsymbol and friends are moved to the new class
  1185. Revision 1.2 2002/08/05 18:27:48 carl
  1186. + more more more documentation
  1187. + first version include/exclude (can't test though, not enough scratch for i386 :()...
  1188. Revision 1.1 2002/07/01 18:46:20 peter
  1189. * internal linker
  1190. * reorganized aasm layer
  1191. Revision 1.27 2002/05/18 13:34:04 peter
  1192. * readded missing revisions
  1193. Revision 1.25 2002/05/14 19:34:38 peter
  1194. * removed old logs and updated copyright year
  1195. Revision 1.24 2002/05/14 17:28:08 peter
  1196. * synchronized cpubase between powerpc and i386
  1197. * moved more tables from cpubase to cpuasm
  1198. * tai_align_abstract moved to tainst, cpuasm must define
  1199. the tai_align class now, which may be empty
  1200. Revision 1.23 2002/04/15 18:54:34 carl
  1201. - removed tcpuflags
  1202. Revision 1.22 2002/04/07 13:18:19 carl
  1203. + more documentation
  1204. Revision 1.21 2002/04/07 10:17:40 carl
  1205. - remove packenumfixed (requires version 1.0.2 or later to compile now!)
  1206. + changing some comments so its commented automatically
  1207. Revision 1.20 2002/03/24 19:04:31 carl
  1208. + patch for SPARC from Mazen NEIFER
  1209. }