aasmcpu.pas 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730
  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_const_reg(Op:TAsmOp;SrcReg:TRegister;value:aWord;DstReg:TRegister);
  50. constructor op_const_ref_reg(op:tasmop;_size:topsize;_op1:aword;const _op2:treference;_op3:tregister);
  51. constructor op_const_reg_ref(op:tasmop;_size:topsize;_op1:aword;_op2:tregister;const _op3:treference);
  52. { this is for Jmp instructions }
  53. constructor op_cond_sym(op:tasmop;cond:TAsmCond;_size:topsize;_op1:tasmsymbol);
  54. constructor op_sym(op:tasmop;_size:topsize;_op1:tasmsymbol);
  55. constructor op_sym_ofs(op:tasmop;_size:topsize;_op1:tasmsymbol;_op1ofs:longint);
  56. constructor op_sym_ofs_reg(op:tasmop;_size:topsize;_op1:tasmsymbol;_op1ofs:longint;_op2:tregister);
  57. constructor op_sym_ofs_ref(op:tasmop;_size:topsize;_op1:tasmsymbol;_op1ofs:longint;const _op2:treference);
  58. constructor op_caddr_reg(op:TAsmOp;rgb:TRegister;cnst:Integer;reg:TRegister);
  59. constructor op_raddr_reg(op:TAsmOp;rg1,rg2:TRegister;reg:TRegister);
  60. procedure changeopsize(siz:topsize);
  61. procedure loadcaddr(opidx:longint;aReg:TRegister;cnst:Integer);
  62. procedure loadraddr(opidx:longint;rg1,rg2:TRegister);
  63. private
  64. procedure init(_size:topsize);{this need to be called by all constructor}
  65. public
  66. { the next will reset all instructions that can change in pass 2 }
  67. procedure SetCondition(const c:TAsmCond);
  68. private
  69. { next fields are filled in pass1, so pass2 is faster }
  70. insentry : PInsEntry;
  71. insoffset,
  72. inssize : longint;
  73. LastInsOffset : longint; { need to be public to be reset }
  74. function InsEnd:longint;
  75. function calcsize(p:PInsEntry):longint;
  76. function NeedAddrPrefix(opidx:byte):boolean;
  77. procedure Swatoperands;
  78. end;
  79. PROCEDURE DoneAsm;
  80. PROCEDURE InitAsm;
  81. implementation
  82. uses
  83. cutils,
  84. CpuGas;
  85. const
  86. _size=S_SW;{To be removed soon}
  87. {****************************************************************************
  88. TAI_ALIGN
  89. ****************************************************************************}
  90. constructor tai_align.create(b:byte);
  91. begin
  92. inherited create(b);
  93. reg.enum:= R_NONE;
  94. end;
  95. constructor tai_align.create_op(b:byte; _op:byte);
  96. begin
  97. inherited create_op(b,_op);
  98. reg.enum:= R_NONE;
  99. end;
  100. {*****************************************************************************
  101. Taicpu Constructors
  102. *****************************************************************************}
  103. procedure taicpu.changeopsize(siz:topsize);
  104. begin
  105. opsize:=siz;
  106. end;
  107. procedure taicpu.init(_size:topsize);
  108. begin
  109. opsize:=_size;
  110. end;
  111. constructor taicpu.op_none(op:tasmop);
  112. begin
  113. inherited create(op);
  114. init(_size);
  115. end;
  116. constructor taicpu.op_reg(op:tasmop;reg:tregister);
  117. begin
  118. inherited create(op);
  119. init(_size);
  120. ops:=1;
  121. loadreg(0,reg);
  122. end;
  123. constructor taicpu.op_const(op:tasmop;_op1:aword);
  124. begin
  125. inherited create(op);
  126. init(_size);
  127. ops:=1;
  128. loadconst(0,aword(_op1));
  129. end;
  130. constructor taicpu.op_ref(op:tasmop;const _op1:treference);
  131. begin
  132. inherited create(op);
  133. init(_size);
  134. ops:=1;
  135. loadref(0,_op1);
  136. end;
  137. constructor taicpu.op_reg_reg(op:tasmop;_op1,_op2:tregister);
  138. begin
  139. inherited create(op);
  140. init(_size);
  141. ops:=2;
  142. loadreg(0,_op1);
  143. loadreg(1,_op2);
  144. end;
  145. constructor taicpu.op_reg_const(op:tasmop;_op1:tregister; _op2:aword);
  146. begin
  147. inherited create(op);
  148. init(_size);
  149. ops:=2;
  150. loadreg(0,_op1);
  151. loadconst(1,aword(_op2));
  152. end;
  153. constructor taicpu.op_reg_ref(Op:TAsmOp;Reg:TRegister;const Ref:TReference);
  154. begin
  155. if not(Op in [A_STB..A_STDFQ])
  156. then
  157. fail;
  158. inherited Create(Op);
  159. init(_size);
  160. ops:=2;
  161. LoadReg(0,Reg);
  162. LoadRef(1,Ref);
  163. end;
  164. constructor taicpu.op_const_reg(op:tasmop;_op1:aword;_op2:tregister);
  165. begin
  166. inherited create(op);
  167. init(_size);
  168. ops:=2;
  169. loadconst(0,aword(_op1));
  170. loadreg(1,_op2);
  171. end;
  172. constructor TAiCpu.op_ref_reg(Op:TAsmOp;const Ref:TReference;Reg:TRegister);
  173. begin
  174. if not(Op in [A_JMPL,A_FLUSH,A_LDSB..A_LDDC,A_RETT,A_SWAP])
  175. then
  176. InternalError(2003042900);
  177. inherited Create(Op);
  178. Init(S_SW);
  179. Ops:=2;
  180. LoadRef(0,Ref);
  181. LoadReg(1,Reg);
  182. end;
  183. constructor taicpu.op_ref_ref(op:tasmop;_size:topsize;const _op1,_op2:treference);
  184. begin
  185. inherited create(op);
  186. init(_size);
  187. ops:=2;
  188. loadref(0,_op1);
  189. loadref(1,_op2);
  190. end;
  191. constructor taicpu.op_reg_reg_reg(op:tasmop;_op1,_op2,_op3:tregister);
  192. begin
  193. inherited create(op);
  194. init(_size);
  195. ops:=3;
  196. loadreg(0,_op1);
  197. loadreg(1,_op2);
  198. loadreg(2,_op3);
  199. end;
  200. constructor taicpu.op_reg_const_reg(op:TAsmOp;SrcReg:TRegister;Value:aWord;DstReg:TRegister);
  201. begin
  202. inherited Create(Op);
  203. Init(S_W);
  204. ops:=3;
  205. LoadReg(0,SrcReg);
  206. LoadConst(1,Value);
  207. LoadReg(2,DstReg);
  208. end;
  209. constructor taicpu.op_const_ref_reg(op:tasmop;_size:topsize;_op1:aword;const _op2:treference;_op3:tregister);
  210. begin
  211. inherited create(op);
  212. init(_size);
  213. ops:=3;
  214. loadconst(0,aword(_op1));
  215. loadref(1,_op2);
  216. loadreg(2,_op3);
  217. end;
  218. constructor taicpu.op_const_reg_ref(op:tasmop;_size:topsize;_op1:aword;_op2:tregister;const _op3:treference);
  219. begin
  220. inherited create(op);
  221. init(_size);
  222. ops:=3;
  223. loadconst(0,aword(_op1));
  224. loadreg(1,_op2);
  225. loadref(2,_op3);
  226. end;
  227. constructor taicpu.op_cond_sym(op:tasmop;cond:TAsmCond;_size:topsize;_op1:tasmsymbol);
  228. begin
  229. inherited create(op);
  230. init(_size);
  231. condition:=cond;
  232. ops:=1;
  233. loadsymbol(0,_op1,0);
  234. end;
  235. constructor taicpu.op_sym(op:tasmop;_size:topsize;_op1:tasmsymbol);
  236. begin
  237. inherited create(op);
  238. init(_size);
  239. ops:=1;
  240. loadsymbol(0,_op1,0);
  241. end;
  242. constructor taicpu.op_sym_ofs(op:tasmop;_size:topsize;_op1:tasmsymbol;_op1ofs:longint);
  243. begin
  244. inherited create(op);
  245. init(_size);
  246. ops:=1;
  247. loadsymbol(0,_op1,_op1ofs);
  248. end;
  249. constructor taicpu.op_sym_ofs_reg(op:tasmop;_size:topsize;_op1:tasmsymbol;_op1ofs:longint;_op2:tregister);
  250. begin
  251. inherited create(op);
  252. init(_size);
  253. ops:=2;
  254. loadsymbol(0,_op1,_op1ofs);
  255. loadreg(1,_op2);
  256. end;
  257. constructor taicpu.op_sym_ofs_ref(op:tasmop;_size:topsize;_op1:tasmsymbol;_op1ofs:longint;const _op2:treference);
  258. begin
  259. inherited create(op);
  260. init(_size);
  261. ops:=2;
  262. loadsymbol(0,_op1,_op1ofs);
  263. loadref(1,_op2);
  264. end;
  265. constructor taicpu.op_caddr_reg(op:TAsmOp;rgb:TRegister;cnst:Integer;reg:TRegister);
  266. begin
  267. inherited create(op);
  268. init(S_SW);
  269. ops:=2;
  270. loadcaddr(0,rgb,cnst);
  271. loadreg(1,reg);
  272. end;
  273. constructor taicpu.op_raddr_reg(op:TAsmOp;rg1,rg2,reg:TRegister);
  274. begin
  275. inherited create(op);
  276. init(S_SW);
  277. ops:=2;
  278. loadraddr(0,rg1,rg2);
  279. loadreg(1,reg);
  280. end;
  281. procedure taicpu.Swatoperands;
  282. var
  283. p:TOper;
  284. begin
  285. { Fix the operands which are in AT&T style and we need them in Intel style }
  286. case ops of
  287. 2:begin
  288. { 0,1 -> 1,0 }
  289. p:=oper[0];
  290. oper[0]:=oper[1];
  291. oper[1]:=p;
  292. end;
  293. 3:begin
  294. { 0,1,2 -> 2,1,0 }
  295. p:=oper[0];
  296. oper[0]:=oper[2];
  297. oper[2]:=p;
  298. end;
  299. end;
  300. end;
  301. { This check must be done with the operand in ATT order
  302. i.e.after swapping in the intel reader
  303. but before swapping in the NASM and TASM writers PM }
  304. {*****************************************************************************
  305. Assembler
  306. *****************************************************************************}
  307. type
  308. ea=packed record
  309. sib_present:boolean;
  310. bytes:byte;
  311. size:byte;
  312. modrm:byte;
  313. sib:byte;
  314. end;
  315. function taicpu.InsEnd:longint;
  316. begin
  317. InsEnd:=InsOffset+InsSize;
  318. end;
  319. procedure TAiCpu.SetCondition(const c:TAsmCond);
  320. const
  321. AsmCond2OpCode:array[TAsmCond]of TAsmOp=
  322. (A_BN,A_BNE,A_BE,A_BG,A_BLE,A_BGE,A_BL,A_BGU,A_BLEU,A_BCC,
  323. 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);
  324. begin
  325. inherited SetCondition(c);
  326. if Opcode=A_BA
  327. then
  328. begin
  329. is_jmp:=true;
  330. Opcode:=AsmCond2OpCode[c];
  331. {$IFDEF EXTDEBUG}
  332. WriteLn('In TAiCpu.SetCondition TAsmCond=',cond2str[c],'==>',std_op2str[OpCode]);
  333. {$ENDIF EXTDEBUG}
  334. end;
  335. end;
  336. function taicpu.NeedAddrPrefix(opidx:byte):boolean;
  337. var
  338. i,b:tregister;
  339. begin
  340. { if (OT_MEMORY and (not oper[opidx].ot))=0 then
  341. begin
  342. i:=oper[opidx].ref^.index;
  343. b:=oper[opidx].ref^.base;
  344. if not(i in [R_NONE,R_EAX,R_EBX,R_ECX,R_EDX,R_EBP,R_ESP,R_ESI,R_EDI]) or
  345. not(b in [R_NONE,R_EAX,R_EBX,R_ECX,R_EDX,R_EBP,R_ESP,R_ESI,R_EDI]) then
  346. begin
  347. NeedAddrPrefix:=true;
  348. exit;
  349. end;
  350. end;}
  351. NeedAddrPrefix:=false;
  352. end;
  353. function regval(r:tregister):byte;
  354. begin
  355. {case r of
  356. R_EAX,R_AX,R_AL,R_ES,R_CR0,R_DR0,R_ST,R_ST0,R_MM0,R_XMM0:
  357. regval:=0;
  358. R_ECX,R_CX,R_CL,R_CS,R_DR1,R_ST1,R_MM1,R_XMM1:
  359. regval:=1;
  360. R_EDX,R_DX,R_DL,R_SS,R_CR2,R_DR2,R_ST2,R_MM2,R_XMM2:
  361. regval:=2;
  362. R_EBX,R_BX,R_BL,R_DS,R_CR3,R_DR3,R_TR3,R_ST3,R_MM3,R_XMM3:
  363. regval:=3;
  364. R_ESP,R_SP,R_AH,R_FS,R_CR4,R_TR4,R_ST4,R_MM4,R_XMM4:
  365. regval:=4;
  366. R_EBP,R_BP,R_CH,R_GS,R_TR5,R_ST5,R_MM5,R_XMM5:
  367. regval:=5;
  368. R_ESI,R_SI,R_DH,R_DR6,R_TR6,R_ST6,R_MM6,R_XMM6:
  369. regval:=6;
  370. R_EDI,R_DI,R_BH,R_DR7,R_TR7,R_ST7,R_MM7,R_XMM7:
  371. regval:=7;
  372. else}
  373. begin
  374. internalerror(777001);
  375. regval:=0;
  376. end;
  377. { end;}
  378. end;
  379. function process_ea(const input:toper;var output:ea;rfield:longint):boolean;
  380. {const
  381. regs:array[0..63] of tregister=(
  382. R_MM0, R_EAX, R_AX, R_AL, R_XMM0, R_NONE, R_NONE, R_NONE,
  383. R_MM1, R_ECX, R_CX, R_CL, R_XMM1, R_NONE, R_NONE, R_NONE,
  384. R_MM2, R_EDX, R_DX, R_DL, R_XMM2, R_NONE, R_NONE, R_NONE,
  385. R_MM3, R_EBX, R_BX, R_BL, R_XMM3, R_NONE, R_NONE, R_NONE,
  386. R_MM4, R_ESP, R_SP, R_AH, R_XMM4, R_NONE, R_NONE, R_NONE,
  387. R_MM5, R_EBP, R_BP, R_CH, R_XMM5, R_NONE, R_NONE, R_NONE,
  388. R_MM6, R_ESI, R_SI, R_DH, R_XMM6, R_NONE, R_NONE, R_NONE,
  389. R_MM7, R_EDI, R_DI, R_BH, R_XMM7, R_NONE, R_NONE, R_NONE
  390. );}
  391. var
  392. j:longint;
  393. i,b:tregister;
  394. sym:tasmsymbol;
  395. md,s:byte;
  396. base,index,scalefactor,
  397. o:longint;
  398. begin
  399. process_ea:=false;
  400. { register ? }
  401. { if (input.typ=top_reg) then
  402. begin
  403. j:=0;
  404. while (j<=high(regs)) do
  405. begin
  406. if input.reg=regs[j] then
  407. break;
  408. inc(j);
  409. end;
  410. if j<=high(regs) then
  411. begin
  412. output.sib_present:=false;
  413. output.bytes:=0;
  414. output.modrm:=$c0 or (rfield shl 3) or (j shr 3);
  415. output.size:=1;
  416. process_ea:=true;
  417. end;
  418. exit;
  419. end;}
  420. { memory reference }
  421. i:=input.ref^.index;
  422. b:=input.ref^.base;
  423. s:=input.ref^.scalefactor;
  424. o:=input.ref^.offset+input.ref^.offsetfixup;
  425. sym:=input.ref^.symbol;
  426. { it's direct address }
  427. if (b.enum=R_NONE) and (i.enum=R_NONE) then
  428. begin
  429. { it's a pure offset }
  430. output.sib_present:=false;
  431. output.bytes:=4;
  432. output.modrm:=5 or (rfield shl 3);
  433. end
  434. else
  435. { it's an indirection }
  436. begin
  437. { 16 bit address? }
  438. { if not((i in [R_NONE,R_EAX,R_EBX,R_ECX,R_EDX,R_EBP,R_ESP,R_ESI,R_EDI]) and
  439. (b in [R_NONE,R_EAX,R_EBX,R_ECX,R_EDX,R_EBP,R_ESP,R_ESI,R_EDI])) then
  440. Message(asmw_e_16bit_not_supported);}
  441. {$ifdef OPTEA}
  442. { make single reg base }
  443. if (b=R_NONE) and (s=1) then
  444. begin
  445. b:=i;
  446. i:=R_NONE;
  447. end;
  448. { convert [3,5,9]*EAX to EAX+[2,4,8]*EAX }
  449. { if (b=R_NONE) and
  450. (((s=2) and (i<>R_ESP)) or
  451. (s=3) or (s=5) or (s=9)) then
  452. begin
  453. b:=i;
  454. dec(s);
  455. end;}
  456. { swap ESP into base if scalefactor is 1 }
  457. { if (s=1) and (i=R_ESP) then
  458. begin
  459. i:=b;
  460. b:=R_ESP;
  461. end;}
  462. {$endif}
  463. { wrong, for various reasons }
  464. { if (i=R_ESP) or ((s<>1) and (s<>2) and (s<>4) and (s<>8) and (i<>R_NONE)) then
  465. exit;}
  466. { base }
  467. { case b of
  468. R_EAX:base:=0;
  469. R_ECX:base:=1;
  470. R_EDX:base:=2;
  471. R_EBX:base:=3;
  472. R_ESP:base:=4;
  473. R_NONE,
  474. R_EBP:base:=5;
  475. R_ESI:base:=6;
  476. R_EDI:base:=7;
  477. else
  478. exit;
  479. end;}
  480. { index }
  481. { case i of
  482. R_EAX:index:=0;
  483. R_ECX:index:=1;
  484. R_EDX:index:=2;
  485. R_EBX:index:=3;
  486. R_NONE:index:=4;
  487. R_EBP:index:=5;
  488. R_ESI:index:=6;
  489. R_EDI:index:=7;
  490. else
  491. exit;
  492. end;
  493. case s of
  494. 0,
  495. 1:scalefactor:=0;
  496. 2:scalefactor:=1;
  497. 4:scalefactor:=2;
  498. 8:scalefactor:=3;
  499. else
  500. exit;
  501. end;
  502. if (b=R_NONE) or
  503. ((b<>R_EBP) and (o=0) and (sym=nil)) then
  504. md:=0
  505. else
  506. if ((o>=-128) and (o<=127) and (sym=nil)) then
  507. md:=1
  508. else
  509. md:=2;
  510. if (b=R_NONE) or (md=2) then
  511. output.bytes:=4
  512. else
  513. output.bytes:=md;}
  514. { SIB needed ? }
  515. { if (i=R_NONE) and (b<>R_ESP) then
  516. begin
  517. output.sib_present:=false;
  518. output.modrm:=(md shl 6) or (rfield shl 3) or base;
  519. end
  520. else
  521. begin
  522. output.sib_present:=true;
  523. output.modrm:=(md shl 6) or (rfield shl 3) or 4;
  524. output.sib:=(scalefactor shl 6) or (index shl 3) or base;
  525. end;}
  526. end;
  527. if output.sib_present then
  528. output.size:=2+output.bytes
  529. else
  530. output.size:=1+output.bytes;
  531. process_ea:=true;
  532. end;
  533. function taicpu.calcsize(p:PInsEntry):longint;
  534. var
  535. codes:pchar;
  536. c:byte;
  537. len:longint;
  538. ea_data:ea;
  539. begin
  540. len:=0;
  541. codes:=@p^.code;
  542. repeat
  543. c:=ord(codes^);
  544. inc(codes);
  545. case c of
  546. 0:
  547. break;
  548. 1,2,3:
  549. begin
  550. inc(codes,c);
  551. inc(len,c);
  552. end;
  553. 8,9,10:
  554. begin
  555. inc(codes);
  556. inc(len);
  557. end;
  558. 4,5,6,7:
  559. begin
  560. if opsize=S_W then
  561. inc(len,2)
  562. else
  563. inc(len);
  564. end;
  565. 15,
  566. 12,13,14,
  567. 16,17,18,
  568. 20,21,22,
  569. 40,41,42:
  570. inc(len);
  571. 24,25,26,
  572. 31,
  573. 48,49,50:
  574. inc(len,2);
  575. 28,29,30, { we don't have 16 bit immediates code }
  576. 32,33,34,
  577. 52,53,54,
  578. 56,57,58:
  579. inc(len,4);
  580. 192,193,194:
  581. if NeedAddrPrefix(c-192) then
  582. inc(len);
  583. 208:
  584. inc(len);
  585. 200,
  586. 201,
  587. 202,
  588. 209,
  589. 210,
  590. 217,218,219:;
  591. 216:
  592. begin
  593. inc(codes);
  594. inc(len);
  595. end;
  596. 224,225,226:
  597. begin
  598. InternalError(777002);
  599. end;
  600. else
  601. begin
  602. if (c>=64) and (c<=191) then
  603. begin
  604. if not process_ea(oper[(c shr 3) and 7], ea_data, 0) then
  605. Message(asmw_e_invalid_effective_address)
  606. else
  607. inc(len,ea_data.size);
  608. end
  609. else
  610. InternalError(777003);
  611. end;
  612. end;
  613. until false;
  614. calcsize:=len;
  615. end;
  616. procedure taicpu.loadcaddr(opidx:longint;aReg:TRegister;cnst:Integer);
  617. begin
  618. if opidx>=ops
  619. then
  620. ops:=opidx+1;
  621. with oper[opidx] do
  622. begin
  623. typ:=top_caddr;
  624. regb:=aReg;
  625. const13:=cnst;
  626. end;
  627. end;
  628. procedure taicpu.loadraddr(opidx:longint;rg1,rg2:TRegister);
  629. begin
  630. if opidx>=ops
  631. then
  632. ops:=opidx+1;
  633. with oper[opidx] do
  634. begin
  635. typ:=top_caddr;
  636. reg1:=rg1;
  637. reg2:=rg2;
  638. end;
  639. end;
  640. procedure DoneAsm;
  641. begin
  642. end;
  643. procedure InitAsm;
  644. begin
  645. end;
  646. end.
  647. {
  648. $Log$
  649. Revision 1.24 2003-05-07 11:28:26 mazen
  650. - method CheckNonCommutativeOpcode removed as not used
  651. Revision 1.23 2003/05/06 20:27:43 mazen
  652. * A_BI changed to A_BL
  653. Revision 1.22 2003/05/06 15:00:36 mazen
  654. - non used code removed to bring up with powerpc changes
  655. Revision 1.21 2003/04/29 11:06:15 mazen
  656. * test of invalid opcode/operand combination gives internal error
  657. Revision 1.20 2003/04/28 09:40:47 mazen
  658. * Debug message in SetCondition more explicit.
  659. Revision 1.19 2003/03/15 22:51:58 mazen
  660. * remaking sparc rtl compile
  661. Revision 1.18 2003/03/10 21:59:54 mazen
  662. * fixing index overflow in handling new registers arrays.
  663. Revision 1.17 2003/02/18 22:00:20 mazen
  664. * asm condition generation modified by TAiCpu.SetCondition
  665. Revision 1.16 2003/01/08 18:43:58 daniel
  666. * Tregister changed into a record
  667. Revision 1.15 2003/01/05 21:32:35 mazen
  668. * fixing several bugs compiling the RTL
  669. Revision 1.14 2002/12/14 15:02:03 carl
  670. * maxoperands -> max_operands (for portability in rautils.pas)
  671. * fix some range-check errors with loadconst
  672. + add ncgadd unit to m68k
  673. * some bugfix of a_param_reg with LOC_CREFERENCE
  674. Revision 1.13 2002/11/17 16:32:04 carl
  675. * memory optimization (3-4%) : cleanup of tai fields,
  676. cleanup of tdef and tsym fields.
  677. * make it work for m68k
  678. Revision 1.12 2002/11/10 19:07:46 mazen
  679. * SPARC calling mechanism almost OK (as in GCC./mppcsparc )
  680. Revision 1.11 2002/11/06 11:31:24 mazen
  681. * op_reg_reg_reg don't need any more a TOpSize parameter
  682. Revision 1.10 2002/11/05 16:15:00 mazen
  683. *** empty log message ***
  684. Revision 1.9 2002/10/28 20:59:17 mazen
  685. * TOpSize values changed S_L --> S_SW
  686. Revision 1.8 2002/10/22 13:43:01 mazen
  687. - cga.pas redueced to an empty unit
  688. Revision 1.7 2002/10/20 19:01:38 mazen
  689. + op_raddr_reg and op_caddr_reg added to fix functions prologue
  690. Revision 1.6 2002/10/19 20:35:07 mazen
  691. * carl's patch applied
  692. Revision 1.5 2002/10/15 09:00:28 mazen
  693. * sone coding style modified
  694. Revision 1.4 2002/10/13 21:46:07 mazen
  695. * assembler output format fixed
  696. }