tainst.pas 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325
  1. {
  2. $Id$
  3. Copyright (c) 1998-2002 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
  22. cpuinfo,cpubase,aasm,cclasses;
  23. Type
  24. tairegalloc = class(tai)
  25. allocation : boolean;
  26. reg : tregister;
  27. constructor alloc(r : tregister);
  28. constructor dealloc(r : tregister);
  29. end;
  30. taicpu_abstract = class(tai)
  31. condition : TAsmCond;
  32. ops : longint;
  33. oper : array[0..max_operands-1] of toper;
  34. opcode : tasmop;
  35. {$ifdef i386}
  36. segprefix : tregister;
  37. {$endif i386}
  38. is_jmp : boolean; { is this instruction a jump? (needed for optimizer) }
  39. Constructor Create(op : tasmop);
  40. Destructor Destroy;override;
  41. function getcopy:tlinkedlistitem;override;
  42. procedure loadconst(opidx:longint;l:aword);
  43. procedure loadsymbol(opidx:longint;s:tasmsymbol;sofs:longint);
  44. procedure loadref(opidx:longint;const r:treference);
  45. procedure loadreg(opidx:longint;r:tregister);
  46. procedure loadoper(opidx:longint;o:toper);
  47. procedure SetCondition(const c:TAsmCond);
  48. end;
  49. { alignment for operator }
  50. tai_align_abstract = class(tai)
  51. buf : array[0..63] of char; { buf used for fill }
  52. aligntype : byte; { 1 = no align, 2 = word align, 4 = dword align }
  53. fillsize : byte; { real size to fill }
  54. fillop : byte; { value to fill with - optional }
  55. use_op : boolean;
  56. constructor Create(b:byte);
  57. constructor Create_op(b: byte; _op: byte);
  58. function getfillbuf:pchar;virtual;
  59. end;
  60. implementation
  61. uses
  62. verbose;
  63. {*****************************************************************************
  64. TaiRegAlloc
  65. *****************************************************************************}
  66. constructor tairegalloc.alloc(r : tregister);
  67. begin
  68. inherited create;
  69. typ:=ait_regalloc;
  70. allocation:=true;
  71. reg:=r;
  72. end;
  73. constructor tairegalloc.dealloc(r : tregister);
  74. begin
  75. inherited create;
  76. typ:=ait_regalloc;
  77. allocation:=false;
  78. reg:=r;
  79. end;
  80. {*****************************************************************************
  81. TaiInstruction
  82. *****************************************************************************}
  83. constructor taicpu_abstract.Create(op : tasmop);
  84. begin
  85. inherited create;
  86. typ:=ait_instruction;
  87. is_jmp:=false;
  88. opcode:=op;
  89. ops:=0;
  90. fillchar(condition,sizeof(condition),0);
  91. fillchar(oper,sizeof(oper),0);
  92. end;
  93. destructor taicpu_abstract.Destroy;
  94. var
  95. i : longint;
  96. begin
  97. for i:=0 to ops-1 do
  98. case oper[i].typ of
  99. top_ref:
  100. dispose(oper[i].ref);
  101. top_symbol:
  102. dec(tasmsymbol(oper[i].sym).refs);
  103. end;
  104. inherited destroy;
  105. end;
  106. { ---------------------------------------------------------------------
  107. Loading of operands.
  108. ---------------------------------------------------------------------}
  109. procedure taicpu_abstract.loadconst(opidx:longint;l:aword);
  110. begin
  111. if opidx>=ops then
  112. ops:=opidx+1;
  113. with oper[opidx] do
  114. begin
  115. if typ=top_ref then
  116. dispose(ref);
  117. val:=l;
  118. typ:=top_const;
  119. end;
  120. end;
  121. procedure taicpu_abstract.loadsymbol(opidx:longint;s:tasmsymbol;sofs:longint);
  122. begin
  123. if not assigned(s) then
  124. internalerror(200204251);
  125. if opidx>=ops then
  126. ops:=opidx+1;
  127. with oper[opidx] do
  128. begin
  129. if typ=top_ref then
  130. dispose(ref);
  131. sym:=s;
  132. symofs:=sofs;
  133. typ:=top_symbol;
  134. end;
  135. inc(s.refs);
  136. end;
  137. procedure taicpu_abstract.loadref(opidx:longint;const r:treference);
  138. begin
  139. if opidx>=ops then
  140. ops:=opidx+1;
  141. with oper[opidx] do
  142. begin
  143. if typ<>top_ref then
  144. new(ref);
  145. ref^:=r;
  146. {$ifdef i386}
  147. { We allow this exception for i386, since overloading this would be
  148. too much of a a speed penalty}
  149. if not(ref^.segment in [R_DS,R_NO]) then
  150. segprefix:=ref^.segment;
  151. {$endif}
  152. typ:=top_ref;
  153. { mark symbol as used }
  154. if assigned(ref^.symbol) then
  155. inc(ref^.symbol.refs);
  156. end;
  157. end;
  158. procedure taicpu_abstract.loadreg(opidx:longint;r:tregister);
  159. begin
  160. if opidx>=ops then
  161. ops:=opidx+1;
  162. with oper[opidx] do
  163. begin
  164. if typ=top_ref then
  165. dispose(ref);
  166. reg:=r;
  167. typ:=top_reg;
  168. end;
  169. end;
  170. procedure taicpu_abstract.loadoper(opidx:longint;o:toper);
  171. begin
  172. if opidx>=ops then
  173. ops:=opidx+1;
  174. if oper[opidx].typ=top_ref then
  175. dispose(oper[opidx].ref);
  176. oper[opidx]:=o;
  177. { copy also the reference }
  178. if oper[opidx].typ=top_ref then
  179. begin
  180. new(oper[opidx].ref);
  181. oper[opidx].ref^:=o.ref^;
  182. end;
  183. end;
  184. { ---------------------------------------------------------------------
  185. Miscellaneous methods.
  186. ---------------------------------------------------------------------}
  187. procedure taicpu_abstract.SetCondition(const c:TAsmCond);
  188. begin
  189. condition:=c;
  190. end;
  191. Function taicpu_abstract.getcopy:tlinkedlistitem;
  192. var
  193. i : longint;
  194. p : tlinkedlistitem;
  195. begin
  196. p:=inherited getcopy;
  197. { make a copy of the references }
  198. for i:=1 to ops do
  199. if (taicpu_abstract(p).oper[i-1].typ=top_ref) then
  200. begin
  201. new(taicpu_abstract(p).oper[i-1].ref);
  202. taicpu_abstract(p).oper[i-1].ref^:=oper[i-1].ref^;
  203. end;
  204. getcopy:=p;
  205. end;
  206. {****************************************************************************
  207. tai_align_abstract
  208. ****************************************************************************}
  209. constructor tai_align_abstract.Create(b: byte);
  210. begin
  211. inherited Create;
  212. typ:=ait_align;
  213. if b in [1,2,4,8,16,32] then
  214. aligntype := b
  215. else
  216. aligntype := 1;
  217. fillsize:=0;
  218. fillop:=0;
  219. use_op:=false;
  220. end;
  221. constructor tai_align_abstract.Create_op(b: byte; _op: byte);
  222. begin
  223. inherited Create;
  224. typ:=ait_align;
  225. if b in [1,2,4,8,16,32] then
  226. aligntype := b
  227. else
  228. aligntype := 1;
  229. fillsize:=0;
  230. fillop:=_op;
  231. use_op:=true;
  232. fillchar(buf,sizeof(buf),_op)
  233. end;
  234. function tai_align_abstract.getfillbuf:pchar;
  235. begin
  236. getfillbuf:=@buf;
  237. end;
  238. end.
  239. {
  240. $Log$
  241. Revision 1.9 2002-05-18 13:34:21 peter
  242. * readded missing revisions
  243. Revision 1.7 2002/05/14 19:34:52 peter
  244. * removed old logs and updated copyright year
  245. Revision 1.6 2002/05/14 17:28:09 peter
  246. * synchronized cpubase between powerpc and i386
  247. * moved more tables from cpubase to cpuasm
  248. * tai_align_abstract moved to tainst, cpuasm must define
  249. the tai_align class now, which may be empty
  250. Revision 1.5 2002/04/25 20:16:39 peter
  251. * moved more routines from cga/n386util
  252. Revision 1.4 2002/04/02 17:11:32 peter
  253. * tlocation,treference update
  254. * LOC_CONSTANT added for better constant handling
  255. * secondadd splitted in multiple routines
  256. * location_force_reg added for loading a location to a register
  257. of a specified size
  258. * secondassignment parses now first the right and then the left node
  259. (this is compatible with Kylix). This saves a lot of push/pop especially
  260. with string operations
  261. * adapted some routines to use the new cg methods
  262. }