aasmcpu.pas 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397
  1. {*****************************************************************************
  2. $Id$
  3. Copyright (c) 1998-2000 by Florian Klaempfl and Peter Vreman
  4. * This code was inspired by the NASM sources
  5. The Netwide Assembler is copyright (C) 1996 Simon Tatham and
  6. Julian Hall. All rights reserved.
  7. This program is free software; you can redistribute it and/or modify
  8. it under the terms of the GNU General Public License as published by
  9. the Free Software Foundation; either version 2 of the License, or
  10. (at your option) any later version.
  11. This program is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. GNU General Public License for more details.
  15. You should have received a copy of the GNU General Public License
  16. along with this program; if not, write to the Free Software
  17. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18. ****************************************************************************}
  19. unit aasmcpu;
  20. {$INCLUDE fpcdefs.inc}
  21. interface
  22. uses
  23. cclasses,globals,verbose,
  24. cpuinfo,cpubase,
  25. symppu,
  26. aasmbase,aasmtai;
  27. const
  28. MaxPrefixes=4;
  29. type
  30. { alignment for operator }
  31. tai_align=class(tai_align_abstract)
  32. reg:tregister;
  33. constructor create(b:byte);
  34. constructor create_op(b:byte; _op:byte);
  35. end;
  36. taicpu = class(taicpu_abstract)
  37. opsize:topsize;
  38. constructor op_none(op:tasmop);
  39. constructor op_reg(op:tasmop;reg:tregister);
  40. constructor op_const(op:tasmop;_op1:aword);
  41. constructor op_ref(op:tasmop;const _op1:treference);
  42. constructor op_reg_reg(op:tasmop;_op1,_op2:tregister);
  43. constructor op_reg_ref(Op:TAsmOp;Reg:TRegister;const Ref:TReference);
  44. constructor op_reg_const(op:tasmop;_op1:tregister;_op2:aword);
  45. constructor op_const_reg(op:tasmop;_op1:aword;_op2:tregister);
  46. constructor op_ref_reg(Op:TAsmOp;const Ref:TReference;Reg:TRegister);
  47. constructor op_ref_ref(op:tasmop;_size:topsize;const _op1,_op2:treference);
  48. constructor op_reg_reg_reg(op:tasmop;_op1,_op2,_op3:tregister);
  49. constructor op_reg_ref_reg(op:tasmop;_op1:TRegister;_op2:TReference;_op3:tregister);
  50. constructor op_reg_const_reg(Op:TAsmOp;SrcReg:TRegister;value:aWord;DstReg:TRegister);
  51. constructor op_const_ref_reg(op:tasmop;_size:topsize;_op1:aword;const _op2:treference;_op3:tregister);
  52. constructor op_const_reg_ref(op:tasmop;_size:topsize;_op1:aword;_op2:tregister;const _op3:treference);
  53. { this is for Jmp instructions }
  54. constructor op_cond_sym(op:tasmop;cond:TAsmCond;_size:topsize;_op1:tasmsymbol);
  55. constructor op_sym(op:tasmop;_size:topsize;_op1:tasmsymbol);
  56. constructor op_sym_ofs(op:tasmop;_size:topsize;_op1:tasmsymbol;_op1ofs:longint);
  57. constructor op_sym_ofs_reg(op:tasmop;_size:topsize;_op1:tasmsymbol;_op1ofs:longint;_op2:tregister);
  58. constructor op_sym_ofs_ref(op:tasmop;_size:topsize;_op1:tasmsymbol;_op1ofs:longint;const _op2:treference);
  59. procedure changeopsize(siz:topsize);
  60. private
  61. procedure init(_size:topsize);{this need to be called by all constructor}
  62. public
  63. { the next will reset all instructions that can change in pass 2 }
  64. procedure SetCondition(const c:TAsmCond);
  65. private
  66. { next fields are filled in pass1, so pass2 is faster }
  67. procedure Swatoperands;
  68. end;
  69. PROCEDURE DoneAsm;
  70. PROCEDURE InitAsm;
  71. implementation
  72. uses
  73. cutils,
  74. CpuGas;
  75. const
  76. _size=S_SW;{To be removed soon}
  77. {****************************************************************************
  78. TAI_ALIGN
  79. ****************************************************************************}
  80. constructor tai_align.create(b:byte);
  81. begin
  82. inherited create(b);
  83. reg.enum:= R_NONE;
  84. end;
  85. constructor tai_align.create_op(b:byte; _op:byte);
  86. begin
  87. inherited create_op(b,_op);
  88. reg.enum:= R_NONE;
  89. end;
  90. {*****************************************************************************
  91. Taicpu Constructors
  92. *****************************************************************************}
  93. procedure taicpu.changeopsize(siz:topsize);
  94. begin
  95. opsize:=siz;
  96. end;
  97. procedure taicpu.init(_size:topsize);
  98. begin
  99. opsize:=_size;
  100. end;
  101. constructor taicpu.op_none(op:tasmop);
  102. begin
  103. inherited create(op);
  104. init(_size);
  105. end;
  106. constructor taicpu.op_reg(op:tasmop;reg:tregister);
  107. begin
  108. inherited create(op);
  109. init(_size);
  110. ops:=1;
  111. loadreg(0,reg);
  112. end;
  113. constructor taicpu.op_const(op:tasmop;_op1:aword);
  114. begin
  115. inherited create(op);
  116. init(_size);
  117. ops:=1;
  118. loadconst(0,aword(_op1));
  119. end;
  120. constructor taicpu.op_ref(op:tasmop;const _op1:treference);
  121. begin
  122. inherited create(op);
  123. init(_size);
  124. ops:=1;
  125. loadref(0,_op1);
  126. end;
  127. constructor taicpu.op_reg_reg(op:tasmop;_op1,_op2:tregister);
  128. begin
  129. inherited create(op);
  130. init(_size);
  131. ops:=2;
  132. loadreg(0,_op1);
  133. loadreg(1,_op2);
  134. end;
  135. constructor taicpu.op_reg_const(op:tasmop;_op1:tregister; _op2:aword);
  136. begin
  137. inherited create(op);
  138. init(_size);
  139. ops:=2;
  140. loadreg(0,_op1);
  141. loadconst(1,aword(_op2));
  142. end;
  143. constructor taicpu.op_reg_ref(Op:TAsmOp;Reg:TRegister;const Ref:TReference);
  144. begin
  145. if not(Op in [A_STB..A_STDFQ])
  146. then
  147. fail;
  148. inherited Create(Op);
  149. init(_size);
  150. ops:=2;
  151. LoadReg(0,Reg);
  152. LoadRef(1,Ref);
  153. end;
  154. constructor taicpu.op_const_reg(op:tasmop;_op1:aword;_op2:tregister);
  155. begin
  156. inherited create(op);
  157. init(_size);
  158. ops:=2;
  159. loadconst(0,aword(_op1));
  160. loadreg(1,_op2);
  161. end;
  162. constructor TAiCpu.op_ref_reg(Op:TAsmOp;const Ref:TReference;Reg:TRegister);
  163. begin
  164. if not(Op in [A_JMPL,A_FLUSH,A_LDSB..A_LDDC,A_RETT,A_SWAP])
  165. then
  166. InternalError(2003042900);
  167. inherited Create(Op);
  168. Init(S_SW);
  169. Ops:=2;
  170. LoadRef(0,Ref);
  171. LoadReg(1,Reg);
  172. end;
  173. constructor taicpu.op_ref_ref(op:tasmop;_size:topsize;const _op1,_op2:treference);
  174. begin
  175. inherited create(op);
  176. init(_size);
  177. ops:=2;
  178. loadref(0,_op1);
  179. loadref(1,_op2);
  180. end;
  181. constructor taicpu.op_reg_reg_reg(op:tasmop;_op1,_op2,_op3:tregister);
  182. begin
  183. inherited create(op);
  184. init(_size);
  185. ops:=3;
  186. loadreg(0,_op1);
  187. loadreg(1,_op2);
  188. loadreg(2,_op3);
  189. end;
  190. constructor taicpu.op_reg_ref_reg(op:tasmop;_op1:TRegister;_op2:TReference;_op3:tregister);
  191. begin
  192. inherited create(op);
  193. init(_size);
  194. ops:=3;
  195. loadreg(0,_op1);
  196. loadref(1,_op2);
  197. loadreg(2,_op3);
  198. end;
  199. constructor taicpu.op_reg_const_reg(op:TAsmOp;SrcReg:TRegister;Value:aWord;DstReg:TRegister);
  200. begin
  201. inherited Create(Op);
  202. Init(S_W);
  203. ops:=3;
  204. LoadReg(0,SrcReg);
  205. LoadConst(1,Value);
  206. LoadReg(2,DstReg);
  207. end;
  208. constructor taicpu.op_const_ref_reg(op:tasmop;_size:topsize;_op1:aword;const _op2:treference;_op3:tregister);
  209. begin
  210. inherited create(op);
  211. init(_size);
  212. ops:=3;
  213. loadconst(0,aword(_op1));
  214. loadref(1,_op2);
  215. loadreg(2,_op3);
  216. end;
  217. constructor taicpu.op_const_reg_ref(op:tasmop;_size:topsize;_op1:aword;_op2:tregister;const _op3:treference);
  218. begin
  219. inherited create(op);
  220. init(_size);
  221. ops:=3;
  222. loadconst(0,aword(_op1));
  223. loadreg(1,_op2);
  224. loadref(2,_op3);
  225. end;
  226. constructor taicpu.op_cond_sym(op:tasmop;cond:TAsmCond;_size:topsize;_op1:tasmsymbol);
  227. begin
  228. inherited create(op);
  229. init(_size);
  230. condition:=cond;
  231. ops:=1;
  232. loadsymbol(0,_op1,0);
  233. end;
  234. constructor taicpu.op_sym(op:tasmop;_size:topsize;_op1:tasmsymbol);
  235. begin
  236. inherited create(op);
  237. init(_size);
  238. ops:=1;
  239. loadsymbol(0,_op1,0);
  240. end;
  241. constructor taicpu.op_sym_ofs(op:tasmop;_size:topsize;_op1:tasmsymbol;_op1ofs:longint);
  242. begin
  243. inherited create(op);
  244. init(_size);
  245. ops:=1;
  246. loadsymbol(0,_op1,_op1ofs);
  247. end;
  248. constructor taicpu.op_sym_ofs_reg(op:tasmop;_size:topsize;_op1:tasmsymbol;_op1ofs:longint;_op2:tregister);
  249. begin
  250. inherited create(op);
  251. init(_size);
  252. ops:=2;
  253. loadsymbol(0,_op1,_op1ofs);
  254. loadreg(1,_op2);
  255. end;
  256. constructor taicpu.op_sym_ofs_ref(op:tasmop;_size:topsize;_op1:tasmsymbol;_op1ofs:longint;const _op2:treference);
  257. begin
  258. inherited create(op);
  259. init(_size);
  260. ops:=2;
  261. loadsymbol(0,_op1,_op1ofs);
  262. loadref(1,_op2);
  263. end;
  264. procedure taicpu.Swatoperands;
  265. var
  266. p:TOper;
  267. begin
  268. { Fix the operands which are in AT&T style and we need them in Intel style }
  269. case ops of
  270. 2:begin
  271. { 0,1 -> 1,0 }
  272. p:=oper[0];
  273. oper[0]:=oper[1];
  274. oper[1]:=p;
  275. end;
  276. 3:begin
  277. { 0,1,2 -> 2,1,0 }
  278. p:=oper[0];
  279. oper[0]:=oper[2];
  280. oper[2]:=p;
  281. end;
  282. end;
  283. end;
  284. { This check must be done with the operand in ATT order
  285. i.e.after swapping in the intel reader
  286. but before swapping in the NASM and TASM writers PM }
  287. {*****************************************************************************
  288. Assembler
  289. *****************************************************************************}
  290. procedure TAiCpu.SetCondition(const c:TAsmCond);
  291. const
  292. AsmCond2OpCode:array[TAsmCond]of TAsmOp=
  293. (A_BN,A_BNE,A_BE,A_BG,A_BLE,A_BGE,A_BL,A_BGU,A_BLEU,A_BCC,
  294. A_BCS,A_BPOS,A_NEG,A_BVC,A_BVS,A_BA,A_BNE,A_NONE,A_NONE,A_NONE,A_NONE,A_NONE,A_NONE,A_NONE,A_NONE,A_NONE,A_NONE,A_NONE,A_NONE,A_NONE,A_NONE);
  295. begin
  296. inherited SetCondition(c);
  297. if Opcode=A_BA
  298. then
  299. begin
  300. is_jmp:=true;
  301. Opcode:=AsmCond2OpCode[c];
  302. {$IFDEF EXTDEBUG}
  303. WriteLn('In TAiCpu.SetCondition TAsmCond=',cond2str[c],'==>',std_op2str[OpCode]);
  304. {$ENDIF EXTDEBUG}
  305. end;
  306. end;
  307. procedure DoneAsm;
  308. begin
  309. end;
  310. procedure InitAsm;
  311. begin
  312. end;
  313. end.
  314. {
  315. $Log$
  316. Revision 1.26 2003-05-28 23:18:31 florian
  317. * started to fix and clean up the sparc port
  318. Revision 1.25 2003/05/07 11:45:02 mazen
  319. - removed unused code
  320. Revision 1.24 2003/05/07 11:28:26 mazen
  321. - method CheckNonCommutativeOpcode removed as not used
  322. Revision 1.23 2003/05/06 20:27:43 mazen
  323. * A_BI changed to A_BL
  324. Revision 1.22 2003/05/06 15:00:36 mazen
  325. - non used code removed to bring up with powerpc changes
  326. Revision 1.21 2003/04/29 11:06:15 mazen
  327. * test of invalid opcode/operand combination gives internal error
  328. Revision 1.20 2003/04/28 09:40:47 mazen
  329. * Debug message in SetCondition more explicit.
  330. Revision 1.19 2003/03/15 22:51:58 mazen
  331. * remaking sparc rtl compile
  332. Revision 1.18 2003/03/10 21:59:54 mazen
  333. * fixing index overflow in handling new registers arrays.
  334. Revision 1.17 2003/02/18 22:00:20 mazen
  335. * asm condition generation modified by TAiCpu.SetCondition
  336. Revision 1.16 2003/01/08 18:43:58 daniel
  337. * Tregister changed into a record
  338. Revision 1.15 2003/01/05 21:32:35 mazen
  339. * fixing several bugs compiling the RTL
  340. Revision 1.14 2002/12/14 15:02:03 carl
  341. * maxoperands -> max_operands (for portability in rautils.pas)
  342. * fix some range-check errors with loadconst
  343. + add ncgadd unit to m68k
  344. * some bugfix of a_param_reg with LOC_CREFERENCE
  345. Revision 1.13 2002/11/17 16:32:04 carl
  346. * memory optimization (3-4%) : cleanup of tai fields,
  347. cleanup of tdef and tsym fields.
  348. * make it work for m68k
  349. Revision 1.12 2002/11/10 19:07:46 mazen
  350. * SPARC calling mechanism almost OK (as in GCC./mppcsparc )
  351. Revision 1.11 2002/11/06 11:31:24 mazen
  352. * op_reg_reg_reg don't need any more a TOpSize parameter
  353. Revision 1.10 2002/11/05 16:15:00 mazen
  354. *** empty log message ***
  355. Revision 1.9 2002/10/28 20:59:17 mazen
  356. * TOpSize values changed S_L --> S_SW
  357. Revision 1.8 2002/10/22 13:43:01 mazen
  358. - cga.pas redueced to an empty unit
  359. Revision 1.7 2002/10/20 19:01:38 mazen
  360. + op_raddr_reg and op_caddr_reg added to fix functions prologue
  361. Revision 1.6 2002/10/19 20:35:07 mazen
  362. * carl's patch applied
  363. Revision 1.5 2002/10/15 09:00:28 mazen
  364. * sone coding style modified
  365. Revision 1.4 2002/10/13 21:46:07 mazen
  366. * assembler output format fixed
  367. }