raarmgas.pas 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776
  1. {
  2. $Id$
  3. Copyright (c) 1998-2002 by Carl Eric Codere and Peter Vreman
  4. Does the parsing for the ARM GNU AS styled inline assembler.
  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 raarmgas;
  19. {$i fpcdefs.inc}
  20. Interface
  21. uses
  22. raatt,raarm,
  23. cpubase;
  24. type
  25. tarmattreader = class(tattreader)
  26. actoppostfix : TOpPostfix;
  27. function is_asmopcode(const s: string):boolean;override;
  28. function is_register(const s:string):boolean;override;
  29. procedure handleopcode;override;
  30. procedure BuildReference(oper : tarmoperand);
  31. procedure BuildOperand(oper : tarmoperand);
  32. procedure BuildOpCode(instr : tarminstruction);
  33. procedure ReadSym(oper : tarmoperand);
  34. procedure ConvertCalljmp(instr : tarminstruction);
  35. end;
  36. Implementation
  37. uses
  38. { helpers }
  39. cutils,
  40. { global }
  41. globtype,globals,verbose,
  42. systems,
  43. { aasm }
  44. cpuinfo,aasmbase,aasmtai,aasmcpu,
  45. { symtable }
  46. symconst,symbase,symtype,symsym,symtable,
  47. { parser }
  48. scanner,
  49. procinfo,
  50. itcpugas,
  51. rabase,rautils,
  52. cgbase,cgobj
  53. ;
  54. function tarmattreader.is_register(const s:string):boolean;
  55. type
  56. treg2str = record
  57. name : string[2];
  58. reg : tregister;
  59. end;
  60. const
  61. extraregs : array[0..19] of treg2str = (
  62. (name: 'A1'; reg : NR_R0),
  63. (name: 'A2'; reg : NR_R1),
  64. (name: 'A3'; reg : NR_R2),
  65. (name: 'A4'; reg : NR_R3),
  66. (name: 'V1'; reg : NR_R4),
  67. (name: 'V2'; reg : NR_R5),
  68. (name: 'V3'; reg : NR_R6),
  69. (name: 'V4'; reg : NR_R7),
  70. (name: 'V5'; reg : NR_R8),
  71. (name: 'V6'; reg : NR_R9),
  72. (name: 'V7'; reg : NR_R10),
  73. (name: 'V8'; reg : NR_R11),
  74. (name: 'WR'; reg : NR_R7),
  75. (name: 'SB'; reg : NR_R9),
  76. (name: 'SL'; reg : NR_R10),
  77. (name: 'FP'; reg : NR_R11),
  78. (name: 'IP'; reg : NR_R12),
  79. (name: 'SP'; reg : NR_R13),
  80. (name: 'LR'; reg : NR_R14),
  81. (name: 'PC'; reg : NR_R15));
  82. var
  83. i : longint;
  84. begin
  85. result:=inherited is_register(s);
  86. { reg found?
  87. possible aliases are always 2 char
  88. }
  89. if result or (length(s)<>2) then
  90. exit;
  91. for i:=low(extraregs) to high(extraregs) do
  92. begin
  93. if s=extraregs[i].name then
  94. begin
  95. actasmregister:=extraregs[i].reg;
  96. result:=true;
  97. actasmtoken:=AS_REGISTER;
  98. exit;
  99. end;
  100. end;
  101. end;
  102. procedure tarmattreader.ReadSym(oper : tarmoperand);
  103. var
  104. tempstr : string;
  105. typesize,l,k : longint;
  106. begin
  107. tempstr:=actasmpattern;
  108. Consume(AS_ID);
  109. { typecasting? }
  110. if (actasmtoken=AS_LPAREN) and
  111. SearchType(tempstr,typesize) then
  112. begin
  113. oper.hastype:=true;
  114. Consume(AS_LPAREN);
  115. BuildOperand(oper);
  116. Consume(AS_RPAREN);
  117. if oper.opr.typ in [OPR_REFERENCE,OPR_LOCAL] then
  118. oper.SetSize(typesize,true);
  119. end
  120. else
  121. if not oper.SetupVar(tempstr,false) then
  122. Message1(sym_e_unknown_id,tempstr);
  123. { record.field ? }
  124. if actasmtoken=AS_DOT then
  125. begin
  126. BuildRecordOffsetSize(tempstr,l,k);
  127. inc(oper.opr.ref.offset,l);
  128. end;
  129. end;
  130. Procedure tarmattreader.BuildReference(oper : tarmoperand);
  131. procedure Consume_RBracket;
  132. begin
  133. if actasmtoken<>AS_RBRACKET then
  134. Begin
  135. Message(asmr_e_invalid_reference_syntax);
  136. RecoverConsume(true);
  137. end
  138. else
  139. begin
  140. Consume(AS_RBRACKET);
  141. if not (actasmtoken in [AS_COMMA,AS_SEPARATOR,AS_END]) then
  142. Begin
  143. Message(asmr_e_invalid_reference_syntax);
  144. RecoverConsume(true);
  145. end;
  146. end;
  147. end;
  148. procedure read_index;
  149. begin
  150. Consume(AS_COMMA);
  151. if actasmtoken=AS_REGISTER then
  152. Begin
  153. oper.opr.ref.index:=actasmregister;
  154. Consume(AS_REGISTER);
  155. end
  156. else if actasmtoken=AS_HASH then
  157. begin
  158. Consume(AS_HASH);
  159. inc(oper.opr.ref.offset,BuildConstExpression(false,true));
  160. end;
  161. Consume_RBracket;
  162. end;
  163. begin
  164. Consume(AS_LBRACKET);
  165. if actasmtoken=AS_REGISTER then
  166. begin
  167. oper.opr.ref.base:=actasmregister;
  168. Consume(AS_REGISTER);
  169. { can either be a register or a right parenthesis }
  170. { (reg) }
  171. if actasmtoken=AS_RBRACKET then
  172. Begin
  173. Consume_RBracket;
  174. oper.opr.ref.addressmode:=AM_POSTINDEXED;
  175. if actasmtoken=AS_COMMA then
  176. read_index;
  177. exit;
  178. end;
  179. if actasmtoken=AS_COMMA then
  180. read_index;
  181. if actasmtoken=AS_NOT then
  182. begin
  183. consume(AS_NOT);
  184. oper.opr.ref.addressmode:=AM_PREINDEXED;
  185. end;
  186. end {end case }
  187. else
  188. Begin
  189. Message(asmr_e_invalid_reference_syntax);
  190. RecoverConsume(false);
  191. end;
  192. end;
  193. Procedure tarmattreader.BuildOperand(oper : tarmoperand);
  194. var
  195. expr : string;
  196. typesize,l : longint;
  197. procedure AddLabelOperand(hl:tasmlabel);
  198. begin
  199. if not(actasmtoken in [AS_PLUS,AS_MINUS,AS_LPAREN]) and
  200. is_calljmp(actopcode) then
  201. begin
  202. oper.opr.typ:=OPR_SYMBOL;
  203. oper.opr.symbol:=hl;
  204. end
  205. else
  206. begin
  207. oper.InitRef;
  208. oper.opr.ref.symbol:=hl;
  209. end;
  210. end;
  211. procedure MaybeRecordOffset;
  212. var
  213. hasdot : boolean;
  214. l,
  215. toffset,
  216. tsize : longint;
  217. begin
  218. if not(actasmtoken in [AS_DOT,AS_PLUS,AS_MINUS]) then
  219. exit;
  220. l:=0;
  221. hasdot:=(actasmtoken=AS_DOT);
  222. if hasdot then
  223. begin
  224. if expr<>'' then
  225. begin
  226. BuildRecordOffsetSize(expr,toffset,tsize);
  227. inc(l,toffset);
  228. oper.SetSize(tsize,true);
  229. end;
  230. end;
  231. if actasmtoken in [AS_PLUS,AS_MINUS] then
  232. inc(l,BuildConstExpression(true,false));
  233. case oper.opr.typ of
  234. OPR_LOCAL :
  235. begin
  236. { don't allow direct access to fields of parameters, because that
  237. will generate buggy code. Allow it only for explicit typecasting }
  238. if hasdot and
  239. (not oper.hastype) and
  240. (tvarsym(oper.opr.localsym).owner.symtabletype=parasymtable) and
  241. (current_procinfo.procdef.proccalloption<>pocall_register) then
  242. Message(asmr_e_cannot_access_field_directly_for_parameters);
  243. inc(oper.opr.localsymofs,l)
  244. end;
  245. OPR_CONSTANT :
  246. inc(oper.opr.val,l);
  247. OPR_REFERENCE :
  248. inc(oper.opr.ref.offset,l);
  249. else
  250. internalerror(200309221);
  251. end;
  252. end;
  253. function MaybeBuildReference:boolean;
  254. { Try to create a reference, if not a reference is found then false
  255. is returned }
  256. begin
  257. MaybeBuildReference:=true;
  258. case actasmtoken of
  259. AS_INTNUM,
  260. AS_MINUS,
  261. AS_PLUS:
  262. Begin
  263. oper.opr.ref.offset:=BuildConstExpression(True,False);
  264. if actasmtoken<>AS_LPAREN then
  265. Message(asmr_e_invalid_reference_syntax)
  266. else
  267. BuildReference(oper);
  268. end;
  269. AS_LPAREN:
  270. BuildReference(oper);
  271. AS_ID: { only a variable is allowed ... }
  272. Begin
  273. ReadSym(oper);
  274. case actasmtoken of
  275. AS_END,
  276. AS_SEPARATOR,
  277. AS_COMMA: ;
  278. AS_LPAREN:
  279. BuildReference(oper);
  280. else
  281. Begin
  282. Message(asmr_e_invalid_reference_syntax);
  283. Consume(actasmtoken);
  284. end;
  285. end; {end case }
  286. end;
  287. else
  288. MaybeBuildReference:=false;
  289. end; { end case }
  290. end;
  291. var
  292. tempreg : tregister;
  293. ireg : tsuperregister;
  294. hl : tasmlabel;
  295. ofs : longint;
  296. registerset : tcpuregisterset;
  297. Begin
  298. expr:='';
  299. case actasmtoken of
  300. AS_LBRACKET: { Memory reference or constant expression }
  301. Begin
  302. oper.InitRef;
  303. BuildReference(oper);
  304. end;
  305. AS_HASH: { Constant expression }
  306. Begin
  307. Consume(AS_HASH);
  308. BuildConstantOperand(oper);
  309. end;
  310. (*
  311. AS_INTNUM,
  312. AS_MINUS,
  313. AS_PLUS:
  314. Begin
  315. { Constant memory offset }
  316. { This must absolutely be followed by ( }
  317. oper.InitRef;
  318. oper.opr.ref.offset:=BuildConstExpression(True,False);
  319. if actasmtoken<>AS_LPAREN then
  320. begin
  321. ofs:=oper.opr.ref.offset;
  322. BuildConstantOperand(oper);
  323. inc(oper.opr.val,ofs);
  324. end
  325. else
  326. BuildReference(oper);
  327. end;
  328. *)
  329. AS_ID: { A constant expression, or a Variable ref. }
  330. Begin
  331. { Local Label ? }
  332. if is_locallabel(actasmpattern) then
  333. begin
  334. CreateLocalLabel(actasmpattern,hl,false);
  335. Consume(AS_ID);
  336. AddLabelOperand(hl);
  337. end
  338. else
  339. { Check for label }
  340. if SearchLabel(actasmpattern,hl,false) then
  341. begin
  342. Consume(AS_ID);
  343. AddLabelOperand(hl);
  344. end
  345. else
  346. { probably a variable or normal expression }
  347. { or a procedure (such as in CALL ID) }
  348. Begin
  349. { is it a constant ? }
  350. if SearchIConstant(actasmpattern,l) then
  351. Begin
  352. if not (oper.opr.typ in [OPR_NONE,OPR_CONSTANT]) then
  353. Message(asmr_e_invalid_operand_type);
  354. BuildConstantOperand(oper);
  355. end
  356. else
  357. begin
  358. expr:=actasmpattern;
  359. Consume(AS_ID);
  360. { typecasting? }
  361. if (actasmtoken=AS_LPAREN) and
  362. SearchType(expr,typesize) then
  363. begin
  364. oper.hastype:=true;
  365. Consume(AS_LPAREN);
  366. BuildOperand(oper);
  367. Consume(AS_RPAREN);
  368. if oper.opr.typ in [OPR_REFERENCE,OPR_LOCAL] then
  369. oper.SetSize(typesize,true);
  370. end
  371. else
  372. begin
  373. if not(oper.SetupVar(expr,false)) then
  374. Begin
  375. { look for special symbols ... }
  376. if expr= '__HIGH' then
  377. begin
  378. consume(AS_LPAREN);
  379. if not oper.setupvar('high'+actasmpattern,false) then
  380. Message1(sym_e_unknown_id,'high'+actasmpattern);
  381. consume(AS_ID);
  382. consume(AS_RPAREN);
  383. end
  384. else
  385. if expr = '__RESULT' then
  386. oper.SetUpResult
  387. else
  388. if expr = '__SELF' then
  389. oper.SetupSelf
  390. else
  391. if expr = '__OLDEBP' then
  392. oper.SetupOldEBP
  393. else
  394. { check for direct symbolic names }
  395. { only if compiling the system unit }
  396. if (cs_compilesystem in aktmoduleswitches) then
  397. begin
  398. if not oper.SetupDirectVar(expr) then
  399. Begin
  400. { not found, finally ... add it anyways ... }
  401. Message1(asmr_w_id_supposed_external,expr);
  402. oper.InitRef;
  403. oper.opr.ref.symbol:=objectlibrary.newasmsymbol(expr);
  404. end;
  405. end
  406. else
  407. Message1(sym_e_unknown_id,expr);
  408. end;
  409. end;
  410. end;
  411. if actasmtoken=AS_DOT then
  412. MaybeRecordOffset;
  413. { add a constant expression? }
  414. if (actasmtoken=AS_PLUS) then
  415. begin
  416. l:=BuildConstExpression(true,false);
  417. case oper.opr.typ of
  418. OPR_CONSTANT :
  419. inc(oper.opr.val,l);
  420. OPR_LOCAL :
  421. inc(oper.opr.localsymofs,l);
  422. OPR_REFERENCE :
  423. inc(oper.opr.ref.offset,l);
  424. else
  425. internalerror(200309202);
  426. end;
  427. end
  428. end;
  429. { Do we have a indexing reference, then parse it also }
  430. if actasmtoken=AS_LPAREN then
  431. BuildReference(oper);
  432. end;
  433. { Register, a variable reference or a constant reference }
  434. AS_REGISTER:
  435. Begin
  436. { save the type of register used. }
  437. tempreg:=actasmregister;
  438. Consume(AS_REGISTER);
  439. if (actasmtoken in [AS_END,AS_SEPARATOR,AS_COMMA]) then
  440. Begin
  441. if not (oper.opr.typ in [OPR_NONE,OPR_REGISTER]) then
  442. Message(asmr_e_invalid_operand_type);
  443. oper.opr.typ:=OPR_REGISTER;
  444. oper.opr.reg:=tempreg;
  445. end
  446. else if (actasmtoken=AS_NOT) and (actopcode in [A_LDM,A_STM]) then
  447. begin
  448. consume(AS_NOT);
  449. oper.opr.typ:=OPR_REFERENCE;
  450. oper.opr.ref.addressmode:=AM_PREINDEXED;
  451. oper.opr.ref.index:=tempreg;
  452. end
  453. else
  454. Message(asmr_e_syn_operand);
  455. end;
  456. { Registerset }
  457. AS_LSBRACKET:
  458. begin
  459. consume(AS_LSBRACKET);
  460. registerset:=[];
  461. while true do
  462. begin
  463. if actasmtoken=AS_REGISTER then
  464. begin
  465. include(registerset,getsupreg(actasmregister));
  466. tempreg:=actasmregister;
  467. consume(AS_REGISTER);
  468. if actasmtoken=AS_MINUS then
  469. begin
  470. consume(AS_MINUS);
  471. for ireg:=getsupreg(tempreg) to getsupreg(actasmregister) do
  472. include(registerset,ireg);
  473. consume(AS_REGISTER);
  474. end;
  475. end
  476. else
  477. consume(AS_REGISTER);
  478. if actasmtoken=AS_COMMA then
  479. consume(AS_COMMA)
  480. else
  481. break;
  482. end;
  483. consume(AS_RSBRACKET);
  484. oper.opr.typ:=OPR_REGSET;
  485. oper.opr.regset:=registerset;
  486. end;
  487. AS_END,
  488. AS_SEPARATOR,
  489. AS_COMMA: ;
  490. else
  491. Begin
  492. Message(asmr_e_syn_operand);
  493. Consume(actasmtoken);
  494. end;
  495. end; { end case }
  496. end;
  497. {*****************************************************************************
  498. tarmattreader
  499. *****************************************************************************}
  500. procedure tarmattreader.BuildOpCode(instr : tarminstruction);
  501. var
  502. operandnum : longint;
  503. Begin
  504. { opcode }
  505. if (actasmtoken<>AS_OPCODE) then
  506. Begin
  507. Message(asmr_e_invalid_or_missing_opcode);
  508. RecoverConsume(true);
  509. exit;
  510. end;
  511. { Fill the instr object with the current state }
  512. with instr do
  513. begin
  514. Opcode:=ActOpcode;
  515. condition:=ActCondition;
  516. oppostfix:=actoppostfix;
  517. end;
  518. { We are reading operands, so opcode will be an AS_ID }
  519. operandnum:=1;
  520. Consume(AS_OPCODE);
  521. { Zero operand opcode ? }
  522. if actasmtoken in [AS_SEPARATOR,AS_END] then
  523. begin
  524. operandnum:=0;
  525. exit;
  526. end;
  527. { Read the operands }
  528. repeat
  529. case actasmtoken of
  530. AS_COMMA: { Operand delimiter }
  531. Begin
  532. if operandnum>Max_Operands then
  533. Message(asmr_e_too_many_operands)
  534. else
  535. Inc(operandnum);
  536. Consume(AS_COMMA);
  537. end;
  538. AS_SEPARATOR,
  539. AS_END : { End of asm operands for this opcode }
  540. begin
  541. break;
  542. end;
  543. else
  544. BuildOperand(instr.Operands[operandnum] as tarmoperand);
  545. end; { end case }
  546. until false;
  547. instr.Ops:=operandnum;
  548. end;
  549. function tarmattreader.is_asmopcode(const s: string):boolean;
  550. const
  551. { sorted by length so longer postfixes will match first }
  552. postfix2strsorted : array[1..19] of string[2] = (
  553. 'EP','SB','BT','SH',
  554. 'IA','IB','DA','DB','FD','FA','ED','EA',
  555. 'B','D','E','P','T','H','S');
  556. postfixsorted : array[1..19] of TOpPostfix = (
  557. PF_EP,PF_SB,PF_BT,PF_SH,
  558. PF_IA,PF_IB,PF_DA,PF_DB,PF_FD,PF_FA,PF_ED,PF_EA,
  559. PF_B,PF_D,PF_E,PF_P,PF_T,PF_H,PF_S);
  560. var
  561. str2opentry: tstr2opentry;
  562. len,
  563. j,
  564. sufidx : longint;
  565. hs : string;
  566. maxlen : longint;
  567. icond : tasmcond;
  568. Begin
  569. { making s a value parameter would break other assembler readers }
  570. hs:=s;
  571. is_asmopcode:=false;
  572. { clear op code }
  573. actopcode:=A_None;
  574. actcondition:=C_None;
  575. { first, handle B else BLS is read wrong }
  576. if ((hs[1]='B') and (length(hs)=3)) then
  577. begin
  578. for icond:=low(tasmcond) to high(tasmcond) do
  579. begin
  580. if copy(hs,2,3)=uppercond2str[icond] then
  581. begin
  582. actopcode:=A_B;
  583. actasmtoken:=AS_OPCODE;
  584. actcondition:=icond;
  585. is_asmopcode:=true;
  586. exit;
  587. end;
  588. end;
  589. end;
  590. maxlen:=max(length(hs),5);
  591. for j:=maxlen downto 1 do
  592. begin
  593. str2opentry:=tstr2opentry(iasmops.search(copy(hs,1,j)));
  594. if assigned(str2opentry) then
  595. begin
  596. actopcode:=str2opentry.op;
  597. actasmtoken:=AS_OPCODE;
  598. { strip op code }
  599. delete(hs,1,j);
  600. break;
  601. end;
  602. end;
  603. if not(assigned(str2opentry)) then
  604. exit;
  605. { search for condition, conditions are always 2 chars }
  606. if length(hs)>1 then
  607. begin
  608. for icond:=low(tasmcond) to high(tasmcond) do
  609. begin
  610. if copy(hs,1,2)=uppercond2str[icond] then
  611. begin
  612. actcondition:=icond;
  613. { strip condition }
  614. delete(hs,1,2);
  615. break;
  616. end;
  617. end;
  618. end;
  619. { check for postfix }
  620. if length(hs)>0 then
  621. begin
  622. for j:=low(postfixsorted) to high(postfixsorted) do
  623. begin
  624. if copy(hs,1,length(postfix2strsorted[j]))=postfix2strsorted[j] then
  625. begin
  626. actoppostfix:=postfixsorted[j];
  627. { strip postfix }
  628. delete(hs,1,length(postfix2strsorted[j]));
  629. break;
  630. end;
  631. end;
  632. end;
  633. { if we stripped all postfixes, it's a valid opcode }
  634. is_asmopcode:=length(hs)=0;
  635. end;
  636. procedure tarmattreader.ConvertCalljmp(instr : tarminstruction);
  637. var
  638. newopr : toprrec;
  639. begin
  640. if instr.Operands[1].opr.typ=OPR_REFERENCE then
  641. begin
  642. newopr.typ:=OPR_SYMBOL;
  643. newopr.symbol:=instr.Operands[1].opr.ref.symbol;
  644. newopr.symofs:=instr.Operands[1].opr.ref.offset;
  645. if (instr.Operands[1].opr.ref.base<>NR_NO) or
  646. (instr.Operands[1].opr.ref.index<>NR_NO) then
  647. Message(asmr_e_syn_operand);
  648. instr.Operands[1].opr:=newopr;
  649. end;
  650. end;
  651. procedure tarmattreader.handleopcode;
  652. var
  653. instr : tarminstruction;
  654. begin
  655. instr:=TarmInstruction.Create(TarmOperand);
  656. BuildOpcode(instr);
  657. if is_calljmp(instr.opcode) then
  658. ConvertCalljmp(instr);
  659. {
  660. instr.AddReferenceSizes;
  661. instr.SetInstructionOpsize;
  662. instr.CheckOperandSizes;
  663. }
  664. instr.ConcatInstruction(curlist);
  665. instr.Free;
  666. actoppostfix:=PF_None;
  667. end;
  668. {*****************************************************************************
  669. Initialize
  670. *****************************************************************************}
  671. const
  672. asmmode_arm_att_info : tasmmodeinfo =
  673. (
  674. id : asmmode_arm_gas;
  675. idtxt : 'GAS';
  676. casmreader : tarmattreader;
  677. );
  678. asmmode_arm_standard_info : tasmmodeinfo =
  679. (
  680. id : asmmode_standard;
  681. idtxt : 'STANDARD';
  682. casmreader : tarmattreader;
  683. );
  684. initialization
  685. RegisterAsmMode(asmmode_arm_att_info);
  686. RegisterAsmMode(asmmode_arm_standard_info);
  687. end.
  688. {
  689. $Log$
  690. Revision 1.7 2004-01-20 21:02:56 florian
  691. * fixed symbol type writing for arm-linux
  692. * fixed assembler generation for abs
  693. Revision 1.6 2003/12/18 17:06:21 florian
  694. * arm compiler compilation fixed
  695. Revision 1.5 2003/12/08 17:43:57 florian
  696. * fixed ldm/stm arm assembler reading
  697. * fixed a_load_reg_reg with OS_8 on ARM
  698. * non supported calling conventions cause only a warning now
  699. Revision 1.4 2003/12/03 17:39:05 florian
  700. * fixed several arm calling conventions issues
  701. * fixed reference reading in the assembler reader
  702. * fixed a_loadaddr_ref_reg
  703. Revision 1.3 2003/11/24 15:17:37 florian
  704. * changed some types to prevend range check errors
  705. Revision 1.2 2003/11/21 16:29:26 florian
  706. * fixed reading of reg. sets in the arm assembler reader
  707. Revision 1.1 2003/11/17 23:23:47 florian
  708. + first part of arm assembler reader
  709. }