aasmcpu.pas 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416
  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: longint);
  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: Longint);
  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_nop: boolean; override;
  55. function is_move:boolean; override;
  56. { register spilling code }
  57. function spilling_decode_loadstore(op: tasmop; var counterpart: tasmop; var wasload: boolean): boolean;override;
  58. function spilling_create_loadstore(op: tasmop; r:tregister; const ref:treference): tai;override;
  59. function spilling_create_load(const ref:treference;r:tregister): tai;override;
  60. function spilling_create_store(r:tregister; const ref:treference): tai;override;
  61. end;
  62. tai_align = class(tai_align_abstract)
  63. { nothing to add }
  64. end;
  65. function setoppostfix(i : taicpu;pf : toppostfix) : taicpu;
  66. function setroundingmode(i : taicpu;rm : troundingmode) : taicpu;
  67. function setcondition(i : taicpu;c : tasmcond) : taicpu;
  68. procedure InitAsm;
  69. procedure DoneAsm;
  70. implementation
  71. uses
  72. cutils,rgobj;
  73. procedure taicpu.loadshifterop(opidx:longint;const so:tshifterop);
  74. begin
  75. allocate_oper(opidx+1);
  76. with oper[opidx]^ do
  77. begin
  78. if typ<>top_shifterop then
  79. begin
  80. clearop(opidx);
  81. new(shifterop);
  82. end;
  83. shifterop^:=so;
  84. typ:=top_shifterop;
  85. end;
  86. end;
  87. procedure taicpu.loadregset(opidx:longint;const s:tcpuregisterset);
  88. begin
  89. allocate_oper(opidx+1);
  90. with oper[opidx]^ do
  91. begin
  92. if typ<>top_regset then
  93. clearop(opidx);
  94. new(regset);
  95. regset^:=s;
  96. typ:=top_regset;
  97. end;
  98. end;
  99. {*****************************************************************************
  100. taicpu Constructors
  101. *****************************************************************************}
  102. constructor taicpu.op_none(op : tasmop);
  103. begin
  104. inherited create(op);
  105. end;
  106. constructor taicpu.op_reg(op : tasmop;_op1 : tregister);
  107. begin
  108. inherited create(op);
  109. ops:=1;
  110. loadreg(0,_op1);
  111. end;
  112. constructor taicpu.op_const(op : tasmop;_op1 : longint);
  113. begin
  114. inherited create(op);
  115. ops:=1;
  116. loadconst(0,aword(_op1));
  117. end;
  118. constructor taicpu.op_reg_reg(op : tasmop;_op1,_op2 : tregister);
  119. begin
  120. inherited create(op);
  121. ops:=2;
  122. loadreg(0,_op1);
  123. loadreg(1,_op2);
  124. end;
  125. constructor taicpu.op_reg_const(op:tasmop; _op1: tregister; _op2: longint);
  126. begin
  127. inherited create(op);
  128. ops:=2;
  129. loadreg(0,_op1);
  130. loadconst(1,aword(_op2));
  131. end;
  132. constructor taicpu.op_ref_regset(op:tasmop; _op1: treference; _op2: tcpuregisterset);
  133. begin
  134. inherited create(op);
  135. ops:=2;
  136. loadref(0,_op1);
  137. loadregset(1,_op2);
  138. end;
  139. constructor taicpu.op_reg_ref(op : tasmop;_op1 : tregister;const _op2 : treference);
  140. begin
  141. inherited create(op);
  142. ops:=2;
  143. loadreg(0,_op1);
  144. loadref(1,_op2);
  145. end;
  146. constructor taicpu.op_reg_reg_reg(op : tasmop;_op1,_op2,_op3 : tregister);
  147. begin
  148. inherited create(op);
  149. ops:=3;
  150. loadreg(0,_op1);
  151. loadreg(1,_op2);
  152. loadreg(2,_op3);
  153. end;
  154. constructor taicpu.op_reg_reg_const(op : tasmop;_op1,_op2 : tregister; _op3: Longint);
  155. begin
  156. inherited create(op);
  157. ops:=3;
  158. loadreg(0,_op1);
  159. loadreg(1,_op2);
  160. loadconst(2,aword(_op3));
  161. end;
  162. constructor taicpu.op_reg_reg_sym_ofs(op : tasmop;_op1,_op2 : tregister; _op3: tasmsymbol;_op3ofs: longint);
  163. begin
  164. inherited create(op);
  165. ops:=3;
  166. loadreg(0,_op1);
  167. loadreg(1,_op2);
  168. loadsymbol(0,_op3,_op3ofs);
  169. end;
  170. constructor taicpu.op_reg_reg_ref(op : tasmop;_op1,_op2 : tregister; const _op3: treference);
  171. begin
  172. inherited create(op);
  173. ops:=3;
  174. loadreg(0,_op1);
  175. loadreg(1,_op2);
  176. loadref(2,_op3);
  177. end;
  178. constructor taicpu.op_reg_reg_shifterop(op : tasmop;_op1,_op2 : tregister;_op3 : tshifterop);
  179. begin
  180. inherited create(op);
  181. ops:=3;
  182. loadreg(0,_op1);
  183. loadreg(1,_op2);
  184. loadshifterop(2,_op3);
  185. end;
  186. constructor taicpu.op_cond_sym(op : tasmop;cond:TAsmCond;_op1 : tasmsymbol);
  187. begin
  188. inherited create(op);
  189. condition:=cond;
  190. ops:=1;
  191. loadsymbol(0,_op1,0);
  192. end;
  193. constructor taicpu.op_sym(op : tasmop;_op1 : tasmsymbol);
  194. begin
  195. inherited create(op);
  196. ops:=1;
  197. loadsymbol(0,_op1,0);
  198. end;
  199. constructor taicpu.op_sym_ofs(op : tasmop;_op1 : tasmsymbol;_op1ofs:longint);
  200. begin
  201. inherited create(op);
  202. ops:=1;
  203. loadsymbol(0,_op1,_op1ofs);
  204. end;
  205. constructor taicpu.op_reg_sym_ofs(op : tasmop;_op1 : tregister;_op2:tasmsymbol;_op2ofs : longint);
  206. begin
  207. inherited create(op);
  208. ops:=2;
  209. loadreg(0,_op1);
  210. loadsymbol(1,_op2,_op2ofs);
  211. end;
  212. constructor taicpu.op_sym_ofs_ref(op : tasmop;_op1 : tasmsymbol;_op1ofs:longint;const _op2 : treference);
  213. begin
  214. inherited create(op);
  215. ops:=2;
  216. loadsymbol(0,_op1,_op1ofs);
  217. loadref(1,_op2);
  218. end;
  219. { ****************************** newra stuff *************************** }
  220. function taicpu.is_nop: boolean;
  221. begin
  222. { we don't insert any more nops than necessary }
  223. is_nop := false;
  224. end;
  225. function taicpu.is_move:boolean;
  226. begin
  227. is_move := opcode=A_MOV;
  228. end;
  229. function taicpu.spilling_decode_loadstore(op: tasmop; var counterpart: tasmop; var wasload: boolean): boolean;
  230. begin
  231. result := true;
  232. wasload := true;
  233. case op of
  234. A_LDR:
  235. begin
  236. counterpart := A_STR;
  237. end;
  238. A_LDM:
  239. internalerror(2003070602);
  240. else
  241. result := false;
  242. end;
  243. end;
  244. function taicpu.spilling_create_loadstore(op: tasmop; r:tregister; const ref:treference): tai;
  245. begin
  246. result:=taicpu.op_reg_ref(opcode,r,ref);
  247. end;
  248. function taicpu.spilling_create_load(const ref:treference;r:tregister): tai;
  249. begin
  250. result:=taicpu.op_reg_ref(A_LDR,r,ref);
  251. end;
  252. function taicpu.spilling_create_store(r:tregister; const ref:treference): tai;
  253. begin
  254. result:=taicpu.op_reg_ref(A_STR,r,ref);
  255. end;
  256. procedure InitAsm;
  257. begin
  258. end;
  259. procedure DoneAsm;
  260. begin
  261. end;
  262. function setoppostfix(i : taicpu;pf : toppostfix) : taicpu;
  263. begin
  264. i.oppostfix:=pf;
  265. result:=i;
  266. end;
  267. function setroundingmode(i : taicpu;rm : troundingmode) : taicpu;
  268. begin
  269. i.roundingmode:=rm;
  270. result:=i;
  271. end;
  272. function setcondition(i : taicpu;c : tasmcond) : taicpu;
  273. begin
  274. i.condition:=c;
  275. result:=i;
  276. end;
  277. end.
  278. {
  279. $Log$
  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. }