tainst.pas 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306
  1. {
  2. $Id$
  3. Copyright (c) 1998-2000 by Michael Van Canneyt
  4. Contains a generic assembler instruction object;
  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 tainst;
  19. {$i fpcdefs.inc}
  20. interface
  21. Uses aasm,cpubase,cpuinfo,cclasses;
  22. Type
  23. tairegalloc = class(tai)
  24. allocation : boolean;
  25. reg : tregister;
  26. constructor alloc(r : tregister);
  27. constructor dealloc(r : tregister);
  28. end;
  29. tainstruction = class(tai)
  30. condition : TAsmCond;
  31. ops : longint;
  32. oper : array[0..max_operands-1] of toper;
  33. opcode : tasmop;
  34. {$ifdef i386}
  35. segprefix : tregister;
  36. {$endif i386}
  37. is_jmp : boolean; { is this instruction a jump? (needed for optimizer) }
  38. Constructor Create(op : tasmop);
  39. Destructor Destroy;override;
  40. function getcopy:tlinkedlistitem;override;
  41. procedure loadconst(opidx:longint;l:aword);
  42. procedure loadsymbol(opidx:longint;s:tasmsymbol;sofs:longint);
  43. procedure loadref(opidx:longint;const r:treference);
  44. procedure loadreg(opidx:longint;r:tregister);
  45. procedure loadoper(opidx:longint;o:toper);
  46. procedure SetCondition(const c:TAsmCond);
  47. end;
  48. implementation
  49. uses
  50. verbose;
  51. {*****************************************************************************
  52. TaiRegAlloc
  53. *****************************************************************************}
  54. constructor tairegalloc.alloc(r : tregister);
  55. begin
  56. inherited create;
  57. typ:=ait_regalloc;
  58. allocation:=true;
  59. reg:=r;
  60. end;
  61. constructor tairegalloc.dealloc(r : tregister);
  62. begin
  63. inherited create;
  64. typ:=ait_regalloc;
  65. allocation:=false;
  66. reg:=r;
  67. end;
  68. { ---------------------------------------------------------------------
  69. TaInstruction Constructor/Destructor
  70. ---------------------------------------------------------------------}
  71. constructor Tainstruction.Create(op : tasmop);
  72. begin
  73. inherited create;
  74. typ:=ait_instruction;
  75. is_jmp:=false;
  76. opcode:=op;
  77. ops:=0;
  78. fillchar(condition,sizeof(condition),0);
  79. fillchar(oper,sizeof(oper),0);
  80. end;
  81. destructor Tainstruction.Destroy;
  82. var
  83. i : longint;
  84. begin
  85. for i:=0 to ops-1 do
  86. case oper[i].typ of
  87. top_ref:
  88. dispose(oper[i].ref);
  89. top_symbol:
  90. dec(tasmsymbol(oper[i].sym).refs);
  91. end;
  92. inherited destroy;
  93. end;
  94. { ---------------------------------------------------------------------
  95. Loading of operands.
  96. ---------------------------------------------------------------------}
  97. procedure tainstruction.loadconst(opidx:longint;l:aword);
  98. begin
  99. if opidx>=ops then
  100. ops:=opidx+1;
  101. with oper[opidx] do
  102. begin
  103. if typ=top_ref then
  104. dispose(ref);
  105. val:=l;
  106. typ:=top_const;
  107. end;
  108. end;
  109. procedure tainstruction.loadsymbol(opidx:longint;s:tasmsymbol;sofs:longint);
  110. begin
  111. if not assigned(s) then
  112. internalerror(200204251);
  113. if opidx>=ops then
  114. ops:=opidx+1;
  115. with oper[opidx] do
  116. begin
  117. if typ=top_ref then
  118. dispose(ref);
  119. sym:=s;
  120. symofs:=sofs;
  121. typ:=top_symbol;
  122. end;
  123. inc(s.refs);
  124. end;
  125. procedure tainstruction.loadref(opidx:longint;const r:treference);
  126. begin
  127. if opidx>=ops then
  128. ops:=opidx+1;
  129. with oper[opidx] do
  130. begin
  131. if typ<>top_ref then
  132. new(ref);
  133. ref^:=r;
  134. {$ifdef i386}
  135. { We allow this exception for i386, since overloading this would be
  136. too much of a a speed penalty}
  137. if not(ref^.segment in [R_DS,R_NO]) then
  138. segprefix:=ref^.segment;
  139. {$endif}
  140. typ:=top_ref;
  141. { mark symbol as used }
  142. if assigned(ref^.symbol) then
  143. inc(ref^.symbol.refs);
  144. end;
  145. end;
  146. procedure tainstruction.loadreg(opidx:longint;r:tregister);
  147. begin
  148. if opidx>=ops then
  149. ops:=opidx+1;
  150. with oper[opidx] do
  151. begin
  152. if typ=top_ref then
  153. dispose(ref);
  154. reg:=r;
  155. typ:=top_reg;
  156. end;
  157. end;
  158. procedure tainstruction.loadoper(opidx:longint;o:toper);
  159. begin
  160. if opidx>=ops then
  161. ops:=opidx+1;
  162. if oper[opidx].typ=top_ref then
  163. dispose(oper[opidx].ref);
  164. oper[opidx]:=o;
  165. { copy also the reference }
  166. if oper[opidx].typ=top_ref then
  167. begin
  168. new(oper[opidx].ref);
  169. oper[opidx].ref^:=o.ref^;
  170. end;
  171. end;
  172. { ---------------------------------------------------------------------
  173. Miscellaneous methods.
  174. ---------------------------------------------------------------------}
  175. procedure tainstruction.SetCondition(const c:TAsmCond);
  176. begin
  177. condition:=c;
  178. end;
  179. Function tainstruction.getcopy:tlinkedlistitem;
  180. var
  181. i : longint;
  182. p : tlinkedlistitem;
  183. begin
  184. p:=inherited getcopy;
  185. { make a copy of the references }
  186. for i:=1 to ops do
  187. if (tainstruction(p).oper[i-1].typ=top_ref) then
  188. begin
  189. new(tainstruction(p).oper[i-1].ref);
  190. tainstruction(p).oper[i-1].ref^:=oper[i-1].ref^;
  191. end;
  192. getcopy:=p;
  193. end;
  194. end.
  195. {
  196. $Log$
  197. Revision 1.8 2002-05-16 19:46:45 carl
  198. + defines.inc -> fpcdefs.inc to avoid conflicts if compiling by hand
  199. + try to fix temp allocation (still in ifdef)
  200. + generic constructor calls
  201. + start of tassembler / tmodulebase class cleanup
  202. Revision 1.5 2002/04/25 20:16:39 peter
  203. * moved more routines from cga/n386util
  204. Revision 1.4 2002/04/02 17:11:32 peter
  205. * tlocation,treference update
  206. * LOC_CONSTANT added for better constant handling
  207. * secondadd splitted in multiple routines
  208. * location_force_reg added for loading a location to a register
  209. of a specified size
  210. * secondassignment parses now first the right and then the left node
  211. (this is compatible with Kylix). This saves a lot of push/pop especially
  212. with string operations
  213. * adapted some routines to use the new cg methods
  214. Revision 1.3 2001/12/29 16:29:08 jonas
  215. * fixed stupid copy-paste bug
  216. Revision 1.2 2001/12/29 15:28:57 jonas
  217. * powerpc/cgcpu.pas compiles :)
  218. * several powerpc-related fixes
  219. * cpuasm unit is now based on common tainst unit
  220. + nppcmat unit for powerpc (almost complete)
  221. Revision 1.1 2001/08/26 13:36:52 florian
  222. * some cg reorganisation
  223. * some PPC updates
  224. Revision 1.1 2000/07/13 06:30:08 michael
  225. + Initial import
  226. Revision 1.6 2000/01/07 01:14:54 peter
  227. * updated copyright to 2000
  228. Revision 1.5 1999/09/10 18:48:11 florian
  229. * some bug fixes (e.g. must_be_valid and procinfo.funcret_is_valid)
  230. * most things for stored properties fixed
  231. Revision 1.4 1999/09/03 13:10:11 jonas
  232. * condition is now zeroed using fillchar
  233. because on powerpc it's a record now
  234. Revision 1.3 1999/08/26 14:52:59 jonas
  235. * added segprefix field for i386 in tainstruction object
  236. Revision 1.2 1999/08/06 16:38:37 jonas
  237. * declared getcopy virtual, since it's already declared as such
  238. in cobjects.pas (FPC doesn't error on that, TP does)
  239. Revision 1.1 1999/08/06 16:04:05 michael
  240. + introduced tainstruction
  241. }