aasmcpu.pas 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419
  1. {
  2. $Id$
  3. Copyright (c) 2003 by Florian Klaempfl
  4. Contains the assembler object for the ARM
  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 aasmcpu;
  19. {$i fpcdefs.inc}
  20. interface
  21. uses
  22. cclasses,aasmtai,
  23. aasmbase,globals,verbose,
  24. cpubase,cpuinfo,cgbase;
  25. const
  26. { "mov reg,reg" source operand number }
  27. O_MOV_SOURCE = 1;
  28. { "mov reg,reg" source operand number }
  29. O_MOV_DEST = 0;
  30. type
  31. taicpu = class(taicpu_abstract)
  32. oppostfix : TOpPostfix;
  33. roundingmode : troundingmode;
  34. procedure loadshifterop(opidx:longint;const so:tshifterop);
  35. procedure loadregset(opidx:longint;const s:tcpuregisterset);
  36. constructor op_none(op : tasmop);
  37. constructor op_reg(op : tasmop;_op1 : tregister);
  38. constructor op_const(op : tasmop;_op1 : longint);
  39. constructor op_reg_reg(op : tasmop;_op1,_op2 : tregister);
  40. constructor op_reg_ref(op : tasmop;_op1 : tregister;const _op2 : treference);
  41. constructor op_reg_const(op:tasmop; _op1: tregister; _op2: aword);
  42. constructor op_ref_regset(op:tasmop; _op1: treference; _op2: tcpuregisterset);
  43. constructor op_reg_reg_reg(op : tasmop;_op1,_op2,_op3 : tregister);
  44. constructor op_reg_reg_const(op : tasmop;_op1,_op2 : tregister; _op3: aword);
  45. constructor op_reg_reg_sym_ofs(op : tasmop;_op1,_op2 : tregister; _op3: tasmsymbol;_op3ofs: longint);
  46. constructor op_reg_reg_ref(op : tasmop;_op1,_op2 : tregister; const _op3: treference);
  47. constructor op_reg_reg_shifterop(op : tasmop;_op1,_op2 : tregister;_op3 : tshifterop);
  48. { this is for Jmp instructions }
  49. constructor op_cond_sym(op : tasmop;cond:TAsmCond;_op1 : tasmsymbol);
  50. constructor op_sym(op : tasmop;_op1 : tasmsymbol);
  51. constructor op_sym_ofs(op : tasmop;_op1 : tasmsymbol;_op1ofs:longint);
  52. constructor op_reg_sym_ofs(op : tasmop;_op1 : tregister;_op2:tasmsymbol;_op2ofs : longint);
  53. constructor op_sym_ofs_ref(op : tasmop;_op1 : tasmsymbol;_op1ofs:longint;const _op2 : treference);
  54. function is_same_reg_move: boolean; override;
  55. function is_reg_move:boolean; override;
  56. { register spilling code }
  57. function spilling_create_load(const ref:treference;r:tregister): tai;override;
  58. function spilling_create_store(r:tregister; const ref:treference): tai;override;
  59. end;
  60. tai_align = class(tai_align_abstract)
  61. { nothing to add }
  62. end;
  63. function setoppostfix(i : taicpu;pf : toppostfix) : taicpu;
  64. function setroundingmode(i : taicpu;rm : troundingmode) : taicpu;
  65. function setcondition(i : taicpu;c : tasmcond) : taicpu;
  66. procedure InitAsm;
  67. procedure DoneAsm;
  68. implementation
  69. uses
  70. cutils,rgobj;
  71. procedure taicpu.loadshifterop(opidx:longint;const so:tshifterop);
  72. begin
  73. allocate_oper(opidx+1);
  74. with oper[opidx]^ do
  75. begin
  76. if typ<>top_shifterop then
  77. begin
  78. clearop(opidx);
  79. new(shifterop);
  80. end;
  81. shifterop^:=so;
  82. typ:=top_shifterop;
  83. end;
  84. end;
  85. procedure taicpu.loadregset(opidx:longint;const s:tcpuregisterset);
  86. begin
  87. allocate_oper(opidx+1);
  88. with oper[opidx]^ do
  89. begin
  90. if typ<>top_regset then
  91. clearop(opidx);
  92. new(regset);
  93. regset^:=s;
  94. typ:=top_regset;
  95. end;
  96. end;
  97. {*****************************************************************************
  98. taicpu Constructors
  99. *****************************************************************************}
  100. constructor taicpu.op_none(op : tasmop);
  101. begin
  102. inherited create(op);
  103. end;
  104. constructor taicpu.op_reg(op : tasmop;_op1 : tregister);
  105. begin
  106. inherited create(op);
  107. ops:=1;
  108. loadreg(0,_op1);
  109. end;
  110. constructor taicpu.op_const(op : tasmop;_op1 : longint);
  111. begin
  112. inherited create(op);
  113. ops:=1;
  114. loadconst(0,aword(_op1));
  115. end;
  116. constructor taicpu.op_reg_reg(op : tasmop;_op1,_op2 : tregister);
  117. begin
  118. inherited create(op);
  119. ops:=2;
  120. loadreg(0,_op1);
  121. loadreg(1,_op2);
  122. end;
  123. constructor taicpu.op_reg_const(op:tasmop; _op1: tregister; _op2: aword);
  124. begin
  125. inherited create(op);
  126. ops:=2;
  127. loadreg(0,_op1);
  128. loadconst(1,aword(_op2));
  129. end;
  130. constructor taicpu.op_ref_regset(op:tasmop; _op1: treference; _op2: tcpuregisterset);
  131. begin
  132. inherited create(op);
  133. ops:=2;
  134. loadref(0,_op1);
  135. loadregset(1,_op2);
  136. end;
  137. constructor taicpu.op_reg_ref(op : tasmop;_op1 : tregister;const _op2 : treference);
  138. begin
  139. inherited create(op);
  140. ops:=2;
  141. loadreg(0,_op1);
  142. loadref(1,_op2);
  143. end;
  144. constructor taicpu.op_reg_reg_reg(op : tasmop;_op1,_op2,_op3 : tregister);
  145. begin
  146. inherited create(op);
  147. ops:=3;
  148. loadreg(0,_op1);
  149. loadreg(1,_op2);
  150. loadreg(2,_op3);
  151. end;
  152. constructor taicpu.op_reg_reg_const(op : tasmop;_op1,_op2 : tregister; _op3: aword);
  153. begin
  154. inherited create(op);
  155. ops:=3;
  156. loadreg(0,_op1);
  157. loadreg(1,_op2);
  158. loadconst(2,aword(_op3));
  159. end;
  160. constructor taicpu.op_reg_reg_sym_ofs(op : tasmop;_op1,_op2 : tregister; _op3: tasmsymbol;_op3ofs: longint);
  161. begin
  162. inherited create(op);
  163. ops:=3;
  164. loadreg(0,_op1);
  165. loadreg(1,_op2);
  166. loadsymbol(0,_op3,_op3ofs);
  167. end;
  168. constructor taicpu.op_reg_reg_ref(op : tasmop;_op1,_op2 : tregister; const _op3: treference);
  169. begin
  170. inherited create(op);
  171. ops:=3;
  172. loadreg(0,_op1);
  173. loadreg(1,_op2);
  174. loadref(2,_op3);
  175. end;
  176. constructor taicpu.op_reg_reg_shifterop(op : tasmop;_op1,_op2 : tregister;_op3 : tshifterop);
  177. begin
  178. inherited create(op);
  179. ops:=3;
  180. loadreg(0,_op1);
  181. loadreg(1,_op2);
  182. loadshifterop(2,_op3);
  183. end;
  184. constructor taicpu.op_cond_sym(op : tasmop;cond:TAsmCond;_op1 : tasmsymbol);
  185. begin
  186. inherited create(op);
  187. condition:=cond;
  188. ops:=1;
  189. loadsymbol(0,_op1,0);
  190. end;
  191. constructor taicpu.op_sym(op : tasmop;_op1 : tasmsymbol);
  192. begin
  193. inherited create(op);
  194. ops:=1;
  195. loadsymbol(0,_op1,0);
  196. end;
  197. constructor taicpu.op_sym_ofs(op : tasmop;_op1 : tasmsymbol;_op1ofs:longint);
  198. begin
  199. inherited create(op);
  200. ops:=1;
  201. loadsymbol(0,_op1,_op1ofs);
  202. end;
  203. constructor taicpu.op_reg_sym_ofs(op : tasmop;_op1 : tregister;_op2:tasmsymbol;_op2ofs : longint);
  204. begin
  205. inherited create(op);
  206. ops:=2;
  207. loadreg(0,_op1);
  208. loadsymbol(1,_op2,_op2ofs);
  209. end;
  210. constructor taicpu.op_sym_ofs_ref(op : tasmop;_op1 : tasmsymbol;_op1ofs:longint;const _op2 : treference);
  211. begin
  212. inherited create(op);
  213. ops:=2;
  214. loadsymbol(0,_op1,_op1ofs);
  215. loadref(1,_op2);
  216. end;
  217. { ****************************** newra stuff *************************** }
  218. function taicpu.is_same_reg_move: boolean;
  219. begin
  220. { allow the register allocator to remove unnecessary moves }
  221. result:=is_reg_move and (oper[0]^.reg=oper[1]^.reg);
  222. end;
  223. function taicpu.is_reg_move:boolean;
  224. begin
  225. result:=(opcode=A_MOV) and
  226. (condition=C_None) and
  227. (ops=2) and
  228. (oper[0]^.typ=top_reg) and
  229. (oper[1]^.typ=top_reg);
  230. end;
  231. function taicpu.spilling_create_load(const ref:treference;r:tregister): tai;
  232. begin
  233. result:=taicpu.op_reg_ref(A_LDR,r,ref);
  234. end;
  235. function taicpu.spilling_create_store(r:tregister; const ref:treference): tai;
  236. begin
  237. result:=taicpu.op_reg_ref(A_STR,r,ref);
  238. end;
  239. procedure InitAsm;
  240. begin
  241. end;
  242. procedure DoneAsm;
  243. begin
  244. end;
  245. function setoppostfix(i : taicpu;pf : toppostfix) : taicpu;
  246. begin
  247. i.oppostfix:=pf;
  248. result:=i;
  249. end;
  250. function setroundingmode(i : taicpu;rm : troundingmode) : taicpu;
  251. begin
  252. i.roundingmode:=rm;
  253. result:=i;
  254. end;
  255. function setcondition(i : taicpu;c : tasmcond) : taicpu;
  256. begin
  257. i.condition:=c;
  258. result:=i;
  259. end;
  260. end.
  261. {
  262. $Log$
  263. Revision 1.20 2003-12-28 16:20:09 jonas
  264. - removed unused methods from old generic spilling code
  265. Revision 1.19 2003/12/26 14:02:30 peter
  266. * sparc updates
  267. * use registertype in spill_register
  268. Revision 1.18 2003/12/18 17:06:21 florian
  269. * arm compiler compilation fixed
  270. Revision 1.17 2003/12/03 17:39:05 florian
  271. * fixed several arm calling conventions issues
  272. * fixed reference reading in the assembler reader
  273. * fixed a_loadaddr_ref_reg
  274. Revision 1.16 2003/11/30 19:35:29 florian
  275. * fixed several arm related problems
  276. Revision 1.15 2003/11/29 17:36:56 peter
  277. * fixed is_move
  278. Revision 1.14 2003/11/24 15:17:37 florian
  279. * changed some types to prevend range check errors
  280. Revision 1.13 2003/11/02 14:30:03 florian
  281. * fixed ARM for new reg. allocation scheme
  282. Revision 1.12 2003/09/11 11:54:59 florian
  283. * improved arm code generation
  284. * move some protected and private field around
  285. * the temp. register for register parameters/arguments are now released
  286. before the move to the parameter register is done. This improves
  287. the code in a lot of cases.
  288. Revision 1.11 2003/09/06 11:21:49 florian
  289. * fixed stm and ldm to be usable with preindex operand
  290. Revision 1.10 2003/09/04 21:07:03 florian
  291. * ARM compiler compiles again
  292. Revision 1.9 2003/09/04 00:15:29 florian
  293. * first bunch of adaptions of arm compiler for new register type
  294. Revision 1.8 2003/09/03 11:18:37 florian
  295. * fixed arm concatcopy
  296. + arm support in the common compiler sources added
  297. * moved some generic cg code around
  298. + tfputype added
  299. * ...
  300. Revision 1.7 2003/08/29 21:36:28 florian
  301. * fixed procedure entry/exit code
  302. * started to fix reference handling
  303. Revision 1.6 2003/08/28 00:05:29 florian
  304. * today's arm patches
  305. Revision 1.5 2003/08/27 00:27:56 florian
  306. + same procedure as very day: today's work on arm
  307. Revision 1.4 2003/08/25 23:20:38 florian
  308. + started to implement FPU support for the ARM
  309. * fixed a lot of other things
  310. Revision 1.3 2003/08/24 12:27:26 florian
  311. * continued to work on the arm port
  312. Revision 1.2 2003/08/20 15:50:12 florian
  313. * more arm stuff
  314. Revision 1.1 2003/08/16 13:23:01 florian
  315. * several arm related stuff fixed
  316. }