ra68k.pas 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372
  1. {
  2. Copyright (c) 1998-2003 by Carl Eric Codere and Peter Vreman
  3. Handles the common 68k assembler reader routines
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program; if not, write to the Free Software
  14. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  15. ****************************************************************************
  16. }
  17. unit ra68k;
  18. {$i fpcdefs.inc}
  19. interface
  20. uses
  21. aasmbase,aasmtai,aasmdata,aasmcpu,
  22. cpubase,rautils,cclasses;
  23. type
  24. Tm68kOperand=class(TOperand)
  25. end;
  26. Tm68kInstruction=class(TInstruction)
  27. opsize : topsize;
  28. function ConcatInstruction(p : TAsmList):tai;override;
  29. function ConcatLabeledInstr(p : TAsmList):tai;
  30. end;
  31. implementation
  32. uses
  33. verbose,cgbase;
  34. {*****************************************************************************
  35. TM68kInstruction
  36. *****************************************************************************}
  37. function TM68kInstruction.ConcatInstruction(p : TAsmList):tai;
  38. var
  39. ai : taicpu;
  40. begin
  41. ai:=taicpu(inherited ConcatInstruction(p));
  42. ai.opsize:=opsize;
  43. end;
  44. {
  45. function TM68kInstruction.ConcatInstruction(p : TAsmList):tai;
  46. var
  47. fits : boolean;
  48. begin
  49. writeln('jaj mami');
  50. result:=nil;
  51. fits := FALSE;
  52. { setup specific opcodetions for first pass }
  53. { Setup special operands }
  54. { Convert to general form as to conform to the m68k opcode table }
  55. if (opcode = A_ADDA) or (opcode = A_ADDI)
  56. then opcode := A_ADD
  57. else
  58. { CMPM excluded because of GAS v1.34 BUG }
  59. if (opcode = A_CMPA) or
  60. (opcode = A_CMPI) then
  61. opcode := A_CMP
  62. else
  63. if opcode = A_EORI then
  64. opcode := A_EOR
  65. else
  66. if opcode = A_MOVEA then
  67. opcode := A_MOVE
  68. else
  69. if opcode = A_ORI then
  70. opcode := A_OR
  71. else
  72. if (opcode = A_SUBA) or (opcode = A_SUBI) then
  73. opcode := A_SUB;
  74. { Setup operand types }
  75. (*
  76. in opcode <> A_MOVEM then
  77. begin
  78. while not(fits) do
  79. begin
  80. { set the opcodetion cache, if the opcodetion }
  81. { occurs the first time }
  82. if (it[i].i=opcode) and (ins_cache[opcode]=-1) then
  83. ins_cache[opcode]:=i;
  84. if (it[i].i=opcode) and (instr.ops=it[i].ops) then
  85. begin
  86. { first fit }
  87. case instr.ops of
  88. 0 : begin
  89. fits:=true;
  90. break;
  91. end;
  92. 1 :
  93. begin
  94. if (optyp1 and it[i].o1)<>0 then
  95. begin
  96. fits:=true;
  97. break;
  98. end;
  99. end;
  100. 2 : if ((optyp1 and it[i].o1)<>0) and
  101. ((optyp2 and it[i].o2)<>0) then
  102. begin
  103. fits:=true;
  104. break;
  105. end
  106. 3 : if ((optyp1 and it[i].o1)<>0) and
  107. ((optyp2 and it[i].o2)<>0) and
  108. ((optyp3 and it[i].o3)<>0) then
  109. begin
  110. fits:=true;
  111. break;
  112. end;
  113. end; { end case }
  114. end; { endif }
  115. if it[i].i=A_NONE then
  116. begin
  117. { NO MATCH! }
  118. Message(asmr_e_invalid_combination_opcode_and_operand);
  119. exit;
  120. end;
  121. inc(i);
  122. end; { end while }
  123. *)
  124. fits:=TRUE;
  125. { We add the opcode to the opcode linked list }
  126. if fits then
  127. begin
  128. case ops of
  129. 0:
  130. if opsize <> S_NO then
  131. result:=(taicpu.op_none(opcode,opsize))
  132. else
  133. result:=(taicpu.op_none(opcode,S_NO));
  134. 1: begin
  135. case operands[1].opr.typ of
  136. OPR_SYMBOL:
  137. begin
  138. result:=(taicpu.op_sym_ofs(opcode,
  139. opsize, operands[1].opr.symbol,operands[1].opr.symofs));
  140. end;
  141. OPR_CONSTANT:
  142. begin
  143. result:=(taicpu.op_const(opcode,
  144. opsize, operands[1].opr.val));
  145. end;
  146. OPR_REGISTER:
  147. result:=(taicpu.op_reg(opcode,opsize,operands[1].opr.reg));
  148. OPR_REFERENCE:
  149. if opsize <> S_NO then
  150. begin
  151. result:=(taicpu.op_ref(opcode,
  152. opsize,operands[1].opr.ref));
  153. end
  154. else
  155. begin
  156. { special jmp and call case with }
  157. { symbolic references. }
  158. if opcode in [A_BSR,A_JMP,A_JSR,A_BRA,A_PEA] then
  159. begin
  160. result:=(taicpu.op_ref(opcode,
  161. S_NO,operands[1].opr.ref));
  162. end
  163. else
  164. Message(asmr_e_invalid_opcode_and_operand);
  165. end;
  166. OPR_NONE:
  167. Message(asmr_e_invalid_opcode_and_operand);
  168. else
  169. begin
  170. Message(asmr_e_invalid_opcode_and_operand);
  171. end;
  172. end;
  173. end;
  174. 2: begin
  175. { source }
  176. case operands[1].opr.typ of
  177. { reg,reg }
  178. { reg,ref }
  179. OPR_REGISTER:
  180. begin
  181. case operands[2].opr.typ of
  182. OPR_REGISTER:
  183. begin
  184. result:=(taicpu.op_reg_reg(opcode,
  185. opsize,operands[1].opr.reg,operands[2].opr.reg));
  186. end;
  187. OPR_REFERENCE:
  188. result:=(taicpu.op_reg_ref(opcode,
  189. opsize,operands[1].opr.reg,operands[2].opr.ref));
  190. else { else case }
  191. begin
  192. Message(asmr_e_invalid_opcode_and_operand);
  193. end;
  194. end; { end second operand case for OPR_REGISTER }
  195. end;
  196. { regset, ref }
  197. OPR_regset:
  198. begin
  199. case operands[2].opr.typ of
  200. OPR_REFERENCE :
  201. result:=(taicpu.op_regset_ref(opcode,
  202. opsize,operands[1].opr.regset,operands[2].opr.ref));
  203. else
  204. begin
  205. Message(asmr_e_invalid_opcode_and_operand);
  206. end;
  207. end; { end second operand case for OPR_regset }
  208. end;
  209. { const,reg }
  210. { const,const }
  211. { const,ref }
  212. OPR_CONSTANT:
  213. case operands[2].opr.typ of
  214. { constant, constant does not have a specific size. }
  215. OPR_CONSTANT:
  216. result:=(taicpu.op_const_const(opcode,
  217. S_NO,operands[1].opr.val,operands[2].opr.val));
  218. OPR_REFERENCE:
  219. begin
  220. result:=(taicpu.op_const_ref(opcode,
  221. opsize,operands[1].opr.val,
  222. operands[2].opr.ref))
  223. end;
  224. OPR_REGISTER:
  225. begin
  226. result:=(taicpu.op_const_reg(opcode,
  227. opsize,operands[1].opr.val,
  228. operands[2].opr.reg))
  229. end;
  230. else
  231. begin
  232. Message(asmr_e_invalid_opcode_and_operand);
  233. end;
  234. end; { end second operand case for OPR_CONSTANT }
  235. { ref,reg }
  236. { ref,ref }
  237. OPR_REFERENCE:
  238. case operands[2].opr.typ of
  239. OPR_REGISTER:
  240. begin
  241. result:=(taicpu.op_ref_reg(opcode,
  242. opsize,operands[1].opr.ref,
  243. operands[2].opr.reg));
  244. end;
  245. OPR_regset:
  246. begin
  247. result:=(taicpu.op_ref_regset(opcode,
  248. opsize,operands[1].opr.ref,
  249. operands[2].opr.regset));
  250. end;
  251. OPR_REFERENCE: { special opcodes }
  252. result:=(taicpu.op_ref_ref(opcode,
  253. opsize,operands[1].opr.ref,
  254. operands[2].opr.ref));
  255. else
  256. begin
  257. Message(asmr_e_invalid_opcode_and_operand);
  258. end;
  259. end; { end second operand case for OPR_REFERENCE }
  260. OPR_SYMBOL: case operands[2].opr.typ of
  261. OPR_REFERENCE:
  262. begin
  263. result:=(taicpu.op_sym_ofs_ref(opcode,
  264. opsize,operands[1].opr.symbol,operands[1].opr.symofs,
  265. operands[2].opr.ref))
  266. end;
  267. OPR_REGISTER:
  268. begin
  269. result:=(taicpu.op_sym_ofs_reg(opcode,
  270. opsize,operands[1].opr.symbol,operands[1].opr.symofs,
  271. operands[2].opr.reg))
  272. end;
  273. else
  274. begin
  275. Message(asmr_e_invalid_opcode_and_operand);
  276. end;
  277. end; { end second operand case for OPR_SYMBOL }
  278. else
  279. begin
  280. Message(asmr_e_invalid_opcode_and_operand);
  281. end;
  282. end; { end first operand case }
  283. end;
  284. 3: begin
  285. if (opcode = A_DIVSL) or (opcode = A_DIVUL) or (opcode = A_MULU)
  286. or (opcode = A_MULS) or (opcode = A_DIVS) or (opcode = A_DIVU) then
  287. begin
  288. if (operands[1].opr.typ <> OPR_REGISTER)
  289. or (operands[2].opr.typ <> OPR_REGISTER)
  290. or (operands[3].opr.typ <> OPR_REGISTER) then
  291. begin
  292. Message(asmr_e_invalid_opcode_and_operand);
  293. end
  294. else
  295. begin
  296. result:=(taicpu. op_reg_reg_reg(opcode,opsize,
  297. operands[1].opr.reg,operands[2].opr.reg,operands[3].opr.reg));
  298. end;
  299. end
  300. else
  301. Message(asmr_e_invalid_opcode_and_operand);
  302. end;
  303. end; { end case }
  304. end;
  305. if assigned(result) then
  306. p.concat(result);
  307. end;
  308. }
  309. function TM68kInstruction.ConcatLabeledInstr(p : TAsmList):tai;
  310. begin
  311. if ((opcode >= A_BCC) and (opcode <= A_BVS)) or
  312. (opcode = A_BRA) or (opcode = A_BSR) or
  313. (opcode = A_JMP) or (opcode = A_JSR) or
  314. ((opcode >= A_FBEQ) and (opcode <= A_FBNGLE)) then
  315. begin
  316. if ops > 2 then
  317. Message(asmr_e_invalid_opcode_and_operand)
  318. else if operands[1].opr.typ <> OPR_SYMBOL then
  319. Message(asmr_e_invalid_opcode_and_operand)
  320. else if (operands[1].opr.typ = OPR_SYMBOL) and
  321. (ops = 1) then
  322. if assigned(operands[1].opr.symbol) and
  323. (operands[1].opr.symofs=0) then
  324. result:=taicpu.op_sym(opcode,S_NO,
  325. operands[1].opr.symbol)
  326. else
  327. Message(asmr_e_invalid_opcode_and_operand);
  328. end
  329. else if ((opcode >= A_DBCC) and (opcode <= A_DBF))
  330. or ((opcode >= A_FDBEQ) and (opcode <= A_FDBNGLE)) then
  331. begin
  332. if (ops<>2) or
  333. (operands[1].opr.typ <> OPR_REGISTER) or
  334. (operands[2].opr.typ <> OPR_SYMBOL) or
  335. (operands[2].opr.symofs <> 0) then
  336. Message(asmr_e_invalid_opcode_and_operand)
  337. else
  338. result:=taicpu.op_reg_sym(opcode,opsize,operands[1].opr.reg,
  339. operands[2].opr.symbol);
  340. end
  341. else
  342. Message(asmr_e_invalid_opcode_and_operand);
  343. if assigned(result) then
  344. p.concat(result);
  345. end;
  346. end.