cgcpu.pas 42 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140
  1. {
  2. Copyright (c) 2008 by Florian Klaempfl
  3. Member of the Free Pascal development team
  4. This unit implements the code generator for the AVR
  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 cgcpu;
  19. {$i fpcdefs.inc}
  20. interface
  21. uses
  22. globtype,symtype,symdef,
  23. cgbase,cgutils,cgobj,
  24. aasmbase,aasmcpu,aasmtai,aasmdata,
  25. parabase,
  26. cpubase,cpuinfo,node,cg64f32,rgcpu;
  27. type
  28. { tcgavr }
  29. tcgavr = class(tcg)
  30. { true, if the next arithmetic operation should modify the flags }
  31. cgsetflags : boolean;
  32. procedure init_register_allocators;override;
  33. procedure done_register_allocators;override;
  34. function getintregister(list:TAsmList;size:Tcgsize):Tregister;override;
  35. function getaddressregister(list:TAsmList):Tregister;override;
  36. procedure prepareref(list: TAsmList; var r: treference);
  37. procedure incabsref(list: TAsmList;var r: treference);
  38. procedure a_load_const_cgpara(list : TAsmList;size : tcgsize;a : aint;const paraloc : TCGPara);override;
  39. procedure a_load_ref_cgpara(list : TAsmList;size : tcgsize;const r : treference;const paraloc : TCGPara);override;
  40. procedure a_loadaddr_ref_cgpara(list : TAsmList;const r : treference;const paraloc : TCGPara);override;
  41. procedure a_call_name(list : TAsmList;const s : string; weak: boolean);override;
  42. procedure a_call_reg(list : TAsmList;reg: tregister);override;
  43. procedure a_call_ref(list : TAsmList;ref: treference);override;
  44. procedure a_op_const_reg(list : TAsmList; Op: TOpCG; size: TCGSize; a: aint; reg: TRegister); override;
  45. procedure a_op_reg_reg(list : TAsmList; Op: TOpCG; size: TCGSize; src, dst: TRegister); override;
  46. procedure a_op_const_reg_reg(list: TAsmList; op: TOpCg;
  47. size: tcgsize; a: aint; src, dst: tregister); override;
  48. procedure a_op_reg_reg_reg(list: TAsmList; op: TOpCg;
  49. size: tcgsize; src1, src2, dst: tregister); override;
  50. procedure a_op_const_reg_reg_checkoverflow(list: TAsmList; op: TOpCg; size: tcgsize; a: aint; src, dst: tregister;setflags : boolean;var ovloc : tlocation);override;
  51. procedure a_op_reg_reg_reg_checkoverflow(list: TAsmList; op: TOpCg; size: tcgsize; src1, src2, dst: tregister;setflags : boolean;var ovloc : tlocation);override;
  52. { move instructions }
  53. procedure a_load_const_reg(list : TAsmList; size: tcgsize; a : aint;reg : tregister);override;
  54. procedure a_load_reg_ref(list : TAsmList; fromsize, tosize: tcgsize; reg : tregister;const ref : treference);override;
  55. procedure a_load_ref_reg(list : TAsmList; fromsize, tosize : tcgsize;const Ref : treference;reg : tregister);override;
  56. procedure a_load_reg_reg(list : TAsmList; fromsize, tosize : tcgsize;reg1,reg2 : tregister);override;
  57. { comparison operations }
  58. procedure a_cmp_const_reg_label(list : TAsmList;size : tcgsize;cmp_op : topcmp;a : aint;reg : tregister;
  59. l : tasmlabel);override;
  60. procedure a_cmp_reg_reg_label(list : TAsmList;size : tcgsize;cmp_op : topcmp;reg1,reg2 : tregister;l : tasmlabel); override;
  61. procedure a_jmp_name(list : TAsmList;const s : string); override;
  62. procedure a_jmp_always(list : TAsmList;l: tasmlabel); override;
  63. procedure a_jmp_flags(list : TAsmList;const f : TResFlags;l: tasmlabel); override;
  64. procedure g_flags2reg(list: TAsmList; size: TCgSize; const f: TResFlags; reg: TRegister); override;
  65. procedure g_proc_entry(list : TAsmList;localsize : longint;nostackframe:boolean);override;
  66. procedure g_proc_exit(list : TAsmList;parasize : longint;nostackframe:boolean); override;
  67. procedure a_loadaddr_ref_reg(list : TAsmList;const ref : treference;r : tregister);override;
  68. procedure g_concatcopy(list : TAsmList;const source,dest : treference;len : aint);override;
  69. procedure g_concatcopy_unaligned(list : TAsmList;const source,dest : treference;len : aint);override;
  70. procedure g_concatcopy_move(list : TAsmList;const source,dest : treference;len : aint);
  71. procedure g_concatcopy_internal(list : TAsmList;const source,dest : treference;len : aint;aligned : boolean);
  72. procedure g_overflowcheck(list: TAsmList; const l: tlocation; def: tdef); override;
  73. procedure g_overflowCheck_loc(List:TAsmList;const Loc:TLocation;def:TDef;ovloc : tlocation);override;
  74. // procedure g_save_registers(list : TAsmList);override;
  75. // procedure g_restore_registers(list : TAsmList);override;
  76. procedure a_jmp_cond(list : TAsmList;cond : TOpCmp;l: tasmlabel);
  77. procedure fixref(list : TAsmList;var ref : treference);
  78. function normalize_ref(list:TAsmList;op: tasmop;reg:tregister;ref: treference):treference;
  79. procedure g_intf_wrapper(list: TAsmList; procdef: tprocdef; const labelname: string; ioffset: longint);override;
  80. procedure emit_mov(list: TAsmList;reg2: tregister; reg1: tregister);
  81. end;
  82. tcg64favr = class(tcg64f32)
  83. procedure a_op64_reg_reg(list : TAsmList;op:TOpCG;size : tcgsize;regsrc,regdst : tregister64);override;
  84. procedure a_op64_const_reg(list : TAsmList;op:TOpCG;size : tcgsize;value : int64;reg : tregister64);override;
  85. procedure a_op64_const_reg_reg(list: TAsmList;op:TOpCG;size : tcgsize;value : int64;regsrc,regdst : tregister64);override;
  86. procedure a_op64_reg_reg_reg(list: TAsmList;op:TOpCG;size : tcgsize;regsrc1,regsrc2,regdst : tregister64);override;
  87. procedure a_op64_const_reg_reg_checkoverflow(list: TAsmList;op:TOpCG;size : tcgsize;value : int64;regsrc,regdst : tregister64;setflags : boolean;var ovloc : tlocation);override;
  88. procedure a_op64_reg_reg_reg_checkoverflow(list: TAsmList;op:TOpCG;size : tcgsize;regsrc1,regsrc2,regdst : tregister64;setflags : boolean;var ovloc : tlocation);override;
  89. end;
  90. procedure create_codegen;
  91. const
  92. OpCmp2AsmCond : Array[topcmp] of TAsmCond = (C_NONE,C_EQ,C_GT,
  93. C_LT,C_GE,C_LE,C_NE,C_LS,C_CC,C_CS,C_HI);
  94. implementation
  95. uses
  96. globals,verbose,systems,cutils,
  97. fmodule,
  98. symconst,symsym,
  99. tgobj,
  100. procinfo,cpupi,
  101. paramgr;
  102. procedure tcgavr.init_register_allocators;
  103. begin
  104. inherited init_register_allocators;
  105. { currently, we save R14 always, so we can use it }
  106. rg[R_INTREGISTER]:=trgintcpu.create(R_INTREGISTER,R_SUBWHOLE,
  107. [RS_R0,RS_R1,RS_R2,RS_R3,RS_R4,RS_R5,RS_R6,RS_R7,RS_R8,
  108. RS_R9,RS_R10,RS_R12,RS_R14],first_int_imreg,[]);
  109. end;
  110. procedure tcgavr.done_register_allocators;
  111. begin
  112. rg[R_INTREGISTER].free;
  113. inherited done_register_allocators;
  114. end;
  115. function tcgavr.getintregister(list: TAsmList; size: Tcgsize): Tregister;
  116. var
  117. tmp1,tmp2,tmp3 : TRegister;
  118. begin
  119. case size of
  120. OS_8,OS_S8:
  121. Result:=inherited getintregister(list, size);
  122. OS_16,OS_S16:
  123. begin
  124. Result:=inherited getintregister(list, OS_8);
  125. { ensure that the high register can be retrieved by
  126. GetNextReg
  127. }
  128. if inherited getintregister(list, OS_8)<>GetNextReg(Result) then
  129. internalerror(2011021331);
  130. end;
  131. OS_32,OS_S32:
  132. begin
  133. Result:=inherited getintregister(list, OS_8);
  134. tmp1:=inherited getintregister(list, OS_8);
  135. { ensure that the high register can be retrieved by
  136. GetNextReg
  137. }
  138. if tmp1<>GetNextReg(Result) then
  139. internalerror(2011021332);
  140. tmp2:=inherited getintregister(list, OS_8);
  141. { ensure that the upper register can be retrieved by
  142. GetNextReg
  143. }
  144. if tmp2<>GetNextReg(tmp1) then
  145. internalerror(2011021333);
  146. tmp3:=inherited getintregister(list, OS_8);
  147. { ensure that the upper register can be retrieved by
  148. GetNextReg
  149. }
  150. if tmp3<>GetNextReg(tmp2) then
  151. internalerror(2011021334);
  152. end;
  153. else
  154. internalerror(2011021330);
  155. end;
  156. end;
  157. function tcgavr.getaddressregister(list: TAsmList): Tregister;
  158. var
  159. supreg,i : tsuperregister;
  160. begin
  161. Result:=getintregister(list,OS_16);
  162. supreg:=getsupreg(Result);
  163. for i:=RS_R0 to RS_R25 do
  164. rg[R_INTREGISTER].add_edge(supreg,i);
  165. rg[R_INTREGISTER].add_edge(supreg,RS_R27);
  166. rg[R_INTREGISTER].add_edge(supreg,RS_R29);
  167. rg[R_INTREGISTER].add_edge(supreg,RS_R31);
  168. end;
  169. procedure tcgavr.a_load_const_cgpara(list : TAsmList;size : tcgsize;a : aint;const paraloc : TCGPara);
  170. var
  171. ref: treference;
  172. begin
  173. paraloc.check_simple_location;
  174. paramanager.allocparaloc(list,paraloc.location);
  175. case paraloc.location^.loc of
  176. LOC_REGISTER,LOC_CREGISTER:
  177. a_load_const_reg(list,size,a,paraloc.location^.register);
  178. LOC_REFERENCE:
  179. begin
  180. reference_reset(ref,paraloc.alignment);
  181. ref.base:=paraloc.location^.reference.index;
  182. ref.offset:=paraloc.location^.reference.offset;
  183. a_load_const_ref(list,size,a,ref);
  184. end;
  185. else
  186. internalerror(2002081101);
  187. end;
  188. end;
  189. procedure tcgavr.a_load_ref_cgpara(list : TAsmList;size : tcgsize;const r : treference;const paraloc : TCGPara);
  190. var
  191. tmpref, ref: treference;
  192. location: pcgparalocation;
  193. sizeleft: aint;
  194. begin
  195. location := paraloc.location;
  196. tmpref := r;
  197. sizeleft := paraloc.intsize;
  198. while assigned(location) do
  199. begin
  200. paramanager.allocparaloc(list,location);
  201. case location^.loc of
  202. LOC_REGISTER,LOC_CREGISTER:
  203. a_load_ref_reg(list,location^.size,location^.size,tmpref,location^.register);
  204. LOC_REFERENCE:
  205. begin
  206. reference_reset_base(ref,location^.reference.index,location^.reference.offset,paraloc.alignment);
  207. { doubles in softemu mode have a strange order of registers and references }
  208. if location^.size=OS_32 then
  209. g_concatcopy(list,tmpref,ref,4)
  210. else
  211. begin
  212. g_concatcopy(list,tmpref,ref,sizeleft);
  213. if assigned(location^.next) then
  214. internalerror(2005010710);
  215. end;
  216. end;
  217. LOC_VOID:
  218. begin
  219. // nothing to do
  220. end;
  221. else
  222. internalerror(2002081103);
  223. end;
  224. inc(tmpref.offset,tcgsize2size[location^.size]);
  225. dec(sizeleft,tcgsize2size[location^.size]);
  226. location := location^.next;
  227. end;
  228. end;
  229. procedure tcgavr.a_loadaddr_ref_cgpara(list : TAsmList;const r : treference;const paraloc : TCGPara);
  230. var
  231. ref: treference;
  232. tmpreg: tregister;
  233. begin
  234. paraloc.check_simple_location;
  235. paramanager.allocparaloc(list,paraloc.location);
  236. case paraloc.location^.loc of
  237. LOC_REGISTER,LOC_CREGISTER:
  238. a_loadaddr_ref_reg(list,r,paraloc.location^.register);
  239. LOC_REFERENCE:
  240. begin
  241. reference_reset(ref,paraloc.alignment);
  242. ref.base := paraloc.location^.reference.index;
  243. ref.offset := paraloc.location^.reference.offset;
  244. tmpreg := getintregister(list,OS_ADDR);
  245. a_loadaddr_ref_reg(list,r,tmpreg);
  246. a_load_reg_ref(list,OS_ADDR,OS_ADDR,tmpreg,ref);
  247. end;
  248. else
  249. internalerror(2002080701);
  250. end;
  251. end;
  252. procedure tcgavr.a_call_name(list : TAsmList;const s : string; weak: boolean);
  253. begin
  254. list.concat(taicpu.op_sym(A_RCALL,current_asmdata.RefAsmSymbol(s)));
  255. {
  256. the compiler does not properly set this flag anymore in pass 1, and
  257. for now we only need it after pass 2 (I hope) (JM)
  258. if not(pi_do_call in current_procinfo.flags) then
  259. internalerror(2003060703);
  260. }
  261. include(current_procinfo.flags,pi_do_call);
  262. end;
  263. procedure tcgavr.a_call_reg(list : TAsmList;reg: tregister);
  264. begin
  265. a_reg_alloc(list,NR_ZLO);
  266. a_reg_alloc(list,NR_ZHI);
  267. list.concat(taicpu.op_reg_reg(A_MOV,NR_ZLO,reg));
  268. list.concat(taicpu.op_reg_reg(A_MOV,NR_ZHI,GetHigh(reg)));
  269. list.concat(taicpu.op_none(A_ICALL));
  270. a_reg_dealloc(list,NR_ZLO);
  271. a_reg_dealloc(list,NR_ZHI);
  272. include(current_procinfo.flags,pi_do_call);
  273. end;
  274. procedure tcgavr.a_call_ref(list : TAsmList;ref: treference);
  275. begin
  276. a_reg_alloc(list,NR_ZLO);
  277. a_reg_alloc(list,NR_ZHI);
  278. a_load_ref_reg(list,OS_ADDR,OS_ADDR,ref,NR_ZLO);
  279. list.concat(taicpu.op_none(A_ICALL));
  280. a_reg_dealloc(list,NR_ZLO);
  281. a_reg_dealloc(list,NR_ZHI);
  282. include(current_procinfo.flags,pi_do_call);
  283. end;
  284. procedure tcgavr.a_op_const_reg(list : TAsmList; Op: TOpCG; size: TCGSize; a: aint; reg: TRegister);
  285. begin
  286. a_op_const_reg_reg(list,op,size,a,reg,reg);
  287. end;
  288. procedure tcgavr.a_op_reg_reg(list : TAsmList; Op: TOpCG; size: TCGSize; src, dst: TRegister);
  289. var
  290. tmpreg: tregister;
  291. begin
  292. internalerror(2011021301);
  293. case op of
  294. OP_NEG:
  295. if src<>dst then
  296. a_load_reg_reg(list,size,size,src,dst);
  297. list.concat(taicpu.op_reg(A_NEG,dst));
  298. if size in [OS_S16,OS_16,OS_S32,OS_32] then
  299. begin
  300. tmpreg:=GetNextReg(dst);
  301. list.concat(taicpu.op_reg(A_NOT,S_L,));
  302. list.concat(taicpu.op_reg(A_NEG,S_L,regdst.reglo));
  303. list.concat(taicpu.op_const_reg(A_SBB,S_L,-1,regdst.reghi));
  304. end;
  305. OP_NOT:
  306. begin
  307. for i:=1 to cgsize2size[size] do
  308. begin
  309. if src<>dst then
  310. a_load_reg_reg(list,OS_8,OS_8,src,dst);
  311. list.concat(taicpu.op_reg(A_NOT,S_L,dst));
  312. src:=GetNextReg(src);
  313. dst:=GetNextReg(dst);
  314. end;
  315. end
  316. else
  317. a_op_reg_reg_reg(list,op,size,src,dst,dst);
  318. end;
  319. end;
  320. procedure tcgavr.a_op_const_reg_reg(list: TAsmList; op: TOpCg;
  321. size: tcgsize; a: aint; src, dst: tregister);
  322. var
  323. ovloc : tlocation;
  324. begin
  325. a_op_const_reg_reg_checkoverflow(list,op,size,a,src,dst,false,ovloc);
  326. end;
  327. procedure tcgavr.a_op_reg_reg_reg(list: TAsmList; op: TOpCg;
  328. size: tcgsize; src1, src2, dst: tregister);
  329. var
  330. ovloc : tlocation;
  331. begin
  332. a_op_reg_reg_reg_checkoverflow(list,op,size,src1,src2,dst,false,ovloc);
  333. end;
  334. procedure tcgavr.a_op_const_reg_reg_checkoverflow(list: TAsmList; op: TOpCg; size: tcgsize; a: aint; src, dst: tregister;setflags : boolean;var ovloc : tlocation);
  335. begin
  336. internalerror(2011021302);
  337. end;
  338. procedure tcgavr.a_op_reg_reg_reg_checkoverflow(list: TAsmList; op: TOpCg; size: tcgsize; src1, src2, dst: tregister;setflags : boolean;var ovloc : tlocation);
  339. var
  340. so : tshifterop;
  341. tmpreg,overflowreg : tregister;
  342. asmop : tasmop;
  343. begin
  344. internalerror(2011021303);
  345. ovloc.loc:=LOC_VOID;
  346. case op of
  347. OP_NEG,OP_NOT,
  348. OP_DIV,OP_IDIV:
  349. internalerror(200308281);
  350. OP_SHL:
  351. begin
  352. end;
  353. OP_SHR:
  354. begin
  355. end;
  356. OP_SAR:
  357. begin
  358. end;
  359. OP_IMUL,
  360. OP_MUL:
  361. begin
  362. end;
  363. end;
  364. end;
  365. procedure tcgavr.a_load_const_reg(list : TAsmList; size: tcgsize; a : aint;reg : tregister);
  366. begin
  367. if not(size in [OS_8,OS_S8,OS_16,OS_S16,OS_32,OS_S32]) then
  368. internalerror(2002090902);
  369. end;
  370. function tcgavr.normalize_ref(list:TAsmList;op: tasmop;reg:tregister;ref: treference):treference;
  371. var
  372. tmpreg : tregister;
  373. tmpref : treference;
  374. l : tasmlabel;
  375. begin
  376. tmpreg:=NR_NO;
  377. Result:=ref;
  378. if ref.addressmode<>AM_UNCHANGED then
  379. internalerror(2011021701);
  380. { Be sure to have a base register }
  381. if (ref.base=NR_NO) then
  382. begin
  383. { only symbol+offset? }
  384. if ref.index=NR_NO then
  385. exit;
  386. ref.base:=ref.index;
  387. ref.index:=NR_NO;
  388. end;
  389. if assigned(ref.symbol) or (ref.offset<>0) then
  390. begin
  391. tmpreg:=getaddressregister(list);
  392. reference_reset(tmpref,0);
  393. tmpref.symbol:=ref.symbol;
  394. tmpref.offset:=lo(word(ref.offset));
  395. tmpref.refaddr:=addr_lo8;
  396. list.concat(taicpu.op_reg_reg(A_LDI,tmpreg,tmpref);
  397. tmpref.offset:=hi(word(ref.offset));
  398. tmpref.refaddr:=addr_hi8;
  399. list.concat(taicpu.op_reg_reg(A_LDI,GetNextReg(tmpreg),tmpref);
  400. if (ref.base<>NR_NO) then
  401. begin
  402. list.concat(taicpu.op_reg_reg(A_ADD,tmpreg,ref.base);
  403. list.concat(taicpu.op_reg_reg(A_ADC,GetNextReg(tmpreg),GetNextReg(ref.base));
  404. end;
  405. if (ref.index<>NR_NO) then
  406. begin
  407. list.concat(taicpu.op_reg_reg(A_ADD,tmpreg,ref.base);
  408. list.concat(taicpu.op_reg_reg(A_ADC,GetNextReg(tmpreg),GetNextReg(ref.base));
  409. end;
  410. ref.base:=tmpreg;
  411. ref.index:=NR_NO;
  412. end
  413. else if (ref.base<>NR_NO) and (ref.index<>NR_NO) then
  414. begin
  415. tmpreg:=getaddressregister(list);
  416. list.concat(taicpu.op_reg_reg(A_MOVW,tmpreg,ref.index);
  417. list.concat(taicpu.op_reg_reg(A_ADD,tmpreg,ref.base);
  418. list.concat(taicpu.op_reg_reg(A_ADC,GetNextReg(tmpreg),GetNextReg(ref.base));
  419. ref.base:=tmpreg;
  420. ref.index:=NR_NO;
  421. end;
  422. Result:=ref;
  423. end;
  424. procedure tcgavr.a_load_reg_ref(list : TAsmList; fromsize, tosize: tcgsize; reg : tregister;const ref : treference);
  425. begin
  426. internalerror(2011021305);
  427. end;
  428. procedure tcgavr.prepareref(list : TAsmList; var r : treference);
  429. begin
  430. end;
  431. procedure tcgavr.incref(list: TAsmList; var r: treference);
  432. begin
  433. end;
  434. procedure tcgavr.a_load_ref_reg(list : TAsmList; fromsize, tosize : tcgsize;const Ref : treference;reg : tregister);
  435. var
  436. href : treference;
  437. conv_done: boolean;
  438. tmpreg : tregister;
  439. begin
  440. href:=Ref;
  441. prepareref(list,href);
  442. if (tcgsize2size[fromsize]>32) or (tcgsize2size[tosize]>32) or (fromsize=OS_NO) or (tosize=OS_NO) then
  443. internalerror(2011021307);
  444. conv_done:=false;
  445. if tosize<>fromsize then
  446. begin
  447. conv_done:=true;
  448. if tcgsize2size[tosize]<=tcgsize2size[fromsize] then
  449. fromsize:=tosize;
  450. case fromsize of
  451. OS_8:
  452. begin
  453. list.concat(taicpu.op_reg_ref(A_LD,reg,href));
  454. for i:=2 to tcgsize2size[tosize] do
  455. begin
  456. reg:=GetNextReg(reg);
  457. list.concat(taicpu.op_reg(A_CLR,reg));
  458. end;
  459. end;
  460. OS_S8:
  461. begin
  462. { dest is always at least 16 bit at this point }
  463. list.concat(taicpu.op_reg_ref(A_LD,reg,href));
  464. tmpreg:=reg;
  465. reg2:=GetNextReg(reg);
  466. list.concat(taicpu.op_reg(A_CLR,reg));
  467. list.concat(taicpu.op_reg_const(A_SBIC,tmpreg,7));
  468. list.concat(taicpu.op_reg(A_COM,reg));
  469. tmpreg:=register;
  470. for i:=3 to tcgsize2size[tosize] do
  471. begin
  472. reg:=GetNextReg(reg);
  473. emit_mov(list,reg2,tmpreg);
  474. end;
  475. end;
  476. OS_16:
  477. begin
  478. incref(href);
  479. list.concat(taicpu.op_reg_ref(A_LD,reg,href));
  480. reg:=GetNextReg(reg);
  481. list.concat(taicpu.op_reg_ref(A_LD,reg,href));
  482. for i:=3 to tcgsize2size[tosize] do
  483. begin
  484. reg:=GetNextReg(reg);
  485. list.concat(taicpu.op_reg(A_CLR,reg));
  486. end;
  487. end;
  488. OS_S16:
  489. begin
  490. { dest is always at least 32 bit at this point }
  491. emit_mov(list,reg2,reg1);
  492. reg1:=GetNextReg(reg1);
  493. reg2:=GetNextReg(reg2);
  494. emit_mov(list,reg2,reg1);
  495. reg2:=GetNextReg(reg2);
  496. list.concat(taicpu.op_reg(A_CLR,reg2));
  497. list.concat(taicpu.op_reg_const(A_SBIC,reg1,7));
  498. list.concat(taicpu.op_reg(A_COM,reg2));
  499. tmpreg:=register;
  500. for i:=4 to tcgsize2size[tosize] do
  501. begin
  502. reg2:=GetNextReg(reg2);
  503. emit_mov(list,reg2,tmpreg);
  504. end;
  505. end;
  506. else
  507. conv_done:=false;
  508. end;
  509. end;
  510. if not conv_done and (reg1<>reg2) then
  511. begin
  512. for i:=1 to tcgsize2size[fromsize] do
  513. begin
  514. emit_mov(list,reg2,reg1);
  515. reg1:=GetNextReg(reg1);
  516. reg2:=GetNextReg(reg2);
  517. end;
  518. end;
  519. end;
  520. procedure tcgavr.a_load_reg_reg(list : TAsmList; fromsize, tosize : tcgsize;reg1,reg2 : tregister);
  521. var
  522. conv_done: boolean;
  523. tmpreg : tregister;
  524. begin
  525. if (tcgsize2size[fromsize]>32) or (tcgsize2size[tosize]>32) or (fromsize=OS_NO) or (tosize=OS_NO) then
  526. internalerror(2011021310);
  527. conv_done:=false;
  528. if tosize<>fromsize then
  529. begin
  530. conv_done:=true;
  531. if tcgsize2size[tosize]<=tcgsize2size[fromsize] then
  532. fromsize:=tosize;
  533. case fromsize of
  534. OS_8:
  535. begin
  536. emit_mov(list,reg2,reg1);
  537. for i:=2 to tcgsize2size[tosize] do
  538. begin
  539. reg2:=GetNextReg(reg2);
  540. list.concat(taicpu.op_reg(A_CLR,reg2));
  541. end;
  542. end;
  543. OS_S8:
  544. begin
  545. { dest is always at least 16 bit at this point }
  546. emit_mov(list,reg2,reg1);
  547. reg2:=GetNextReg(reg2);
  548. list.concat(taicpu.op_reg(A_CLR,reg2));
  549. list.concat(taicpu.op_reg_const(A_SBIC,reg1,7));
  550. list.concat(taicpu.op_reg(A_COM,reg2));
  551. tmpreg:=register;
  552. for i:=3 to tcgsize2size[tosize] do
  553. begin
  554. reg2:=GetNextReg(reg2);
  555. emit_mov(list,reg2,tmpreg);
  556. end;
  557. end;
  558. OS_16:
  559. begin
  560. emit_mov(list,reg2,reg1);
  561. reg1:=GetNextReg(reg1);
  562. reg2:=GetNextReg(reg2);
  563. emit_mov(list,reg2,reg1);
  564. for i:=3 to tcgsize2size[tosize] do
  565. begin
  566. reg2:=GetNextReg(reg2);
  567. list.concat(taicpu.op_reg(A_CLR,reg2));
  568. end;
  569. end;
  570. OS_S16:
  571. begin
  572. { dest is always at least 32 bit at this point }
  573. emit_mov(list,reg2,reg1);
  574. reg1:=GetNextReg(reg1);
  575. reg2:=GetNextReg(reg2);
  576. emit_mov(list,reg2,reg1);
  577. reg2:=GetNextReg(reg2);
  578. list.concat(taicpu.op_reg(A_CLR,reg2));
  579. list.concat(taicpu.op_reg_const(A_SBIC,reg1,7));
  580. list.concat(taicpu.op_reg(A_COM,reg2));
  581. tmpreg:=register;
  582. for i:=4 to tcgsize2size[tosize] do
  583. begin
  584. reg2:=GetNextReg(reg2);
  585. emit_mov(list,reg2,tmpreg);
  586. end;
  587. end;
  588. else
  589. conv_done:=false;
  590. end;
  591. end;
  592. if not conv_done and (reg1<>reg2) then
  593. begin
  594. for i:=1 to tcgsize2size[fromsize] do
  595. begin
  596. emit_mov(list,reg2,reg1);
  597. reg1:=GetNextReg(reg1);
  598. reg2:=GetNextReg(reg2);
  599. end;
  600. end;
  601. end;
  602. { comparison operations }
  603. procedure tcgavr.a_cmp_const_reg_label(list : TAsmList;size : tcgsize;cmp_op : topcmp;a : aint;reg : tregister;
  604. l : tasmlabel);
  605. begin
  606. internalerror(2011021311);
  607. end;
  608. procedure tcgavr.a_cmp_reg_reg_label(list : TAsmList;size : tcgsize;cmp_op : topcmp;reg1,reg2 : tregister;l : tasmlabel);
  609. begin
  610. internalerror(2011021312);
  611. end;
  612. procedure tcgavr.a_jmp_name(list : TAsmList;const s : string);
  613. begin
  614. internalerror(2011021313);
  615. end;
  616. procedure tcgavr.a_jmp_always(list : TAsmList;l: tasmlabel);
  617. begin
  618. internalerror(2011021314);
  619. end;
  620. procedure tcgavr.a_jmp_flags(list : TAsmList;const f : TResFlags;l: tasmlabel);
  621. begin
  622. internalerror(2011021315);
  623. end;
  624. procedure tcgavr.g_flags2reg(list: TAsmList; size: TCgSize; const f: TResFlags; reg: TRegister);
  625. begin
  626. internalerror(2011021316);
  627. end;
  628. procedure tcgavr.g_proc_entry(list : TAsmList;localsize : longint;nostackframe:boolean);
  629. {
  630. var
  631. ref : treference;
  632. shift : byte;
  633. firstfloatreg,lastfloatreg,
  634. r : byte;
  635. regs : tcpuregisterset;
  636. }
  637. begin
  638. internalerror(2011021317);
  639. {
  640. LocalSize:=align(LocalSize,4);
  641. if not(nostackframe) then
  642. begin
  643. firstfloatreg:=RS_NO;
  644. { save floating point registers? }
  645. for r:=RS_F0 to RS_F7 do
  646. if r in rg[R_FPUREGISTER].used_in_proc-paramanager.get_volatile_registers_fpu(pocall_stdcall) then
  647. begin
  648. if firstfloatreg=RS_NO then
  649. firstfloatreg:=r;
  650. lastfloatreg:=r;
  651. end;
  652. a_reg_alloc(list,NR_STACK_POINTER_REG);
  653. if current_procinfo.framepointer<>NR_STACK_POINTER_REG then
  654. begin
  655. a_reg_alloc(list,NR_FRAME_POINTER_REG);
  656. a_reg_alloc(list,NR_R12);
  657. list.concat(taicpu.op_reg_reg(A_MOV,NR_R12,NR_STACK_POINTER_REG));
  658. end;
  659. { save int registers }
  660. reference_reset(ref);
  661. ref.index:=NR_STACK_POINTER_REG;
  662. ref.addressmode:=AM_PREINDEXED;
  663. regs:=rg[R_INTREGISTER].used_in_proc-paramanager.get_volatile_registers_int(pocall_stdcall);
  664. if current_procinfo.framepointer<>NR_STACK_POINTER_REG then
  665. regs:=regs+[RS_R11,RS_R12,RS_R14,RS_R15]
  666. else
  667. if (regs<>[]) or (pi_do_call in current_procinfo.flags) then
  668. include(regs,RS_R14);
  669. if regs<>[] then
  670. list.concat(setoppostfix(taicpu.op_ref_regset(A_STM,ref,regs),PF_FD));
  671. if current_procinfo.framepointer<>NR_STACK_POINTER_REG then
  672. list.concat(taicpu.op_reg_reg_const(A_SUB,NR_FRAME_POINTER_REG,NR_R12,4));
  673. { allocate necessary stack size
  674. not necessary according to Yury Sidorov
  675. { don't use a_op_const_reg_reg here because we don't allow register allocations
  676. in the entry/exit code }
  677. if (target_info.system in [system_arm_wince]) and
  678. (localsize>=winstackpagesize) then
  679. begin
  680. if localsize div winstackpagesize<=5 then
  681. begin
  682. if is_shifter_const(localsize,shift) then
  683. list.concat(Taicpu.op_reg_reg_const(A_SUB,NR_STACK_POINTER_REG,NR_STACK_POINTER_REG,localsize))
  684. else
  685. begin
  686. a_load_const_reg(list,OS_ADDR,localsize,NR_R12);
  687. list.concat(taicpu.op_reg_reg_reg(A_SUB,NR_STACK_POINTER_REG,NR_STACK_POINTER_REG,NR_R12));
  688. end;
  689. for i:=1 to localsize div winstackpagesize do
  690. begin
  691. if localsize-i*winstackpagesize<4096 then
  692. reference_reset_base(href,NR_STACK_POINTER_REG,-(localsize-i*winstackpagesize))
  693. else
  694. begin
  695. a_load_const_reg(list,OS_ADDR,-(localsize-i*winstackpagesize),NR_R12);
  696. reference_reset_base(href,NR_STACK_POINTER_REG,0);
  697. href.index:=NR_R12;
  698. end;
  699. { the data stored doesn't matter }
  700. list.concat(Taicpu.op_reg_ref(A_STR,NR_R0,href));
  701. end;
  702. a_reg_dealloc(list,NR_R12);
  703. reference_reset_base(href,NR_STACK_POINTER_REG,0);
  704. { the data stored doesn't matter }
  705. list.concat(Taicpu.op_reg_ref(A_STR,NR_R0,href));
  706. end
  707. else
  708. begin
  709. current_asmdata.getjumplabel(again);
  710. list.concat(Taicpu.op_reg_const(A_MOV,NR_R12,localsize div winstackpagesize));
  711. a_label(list,again);
  712. { always shifterop }
  713. list.concat(Taicpu.op_reg_reg_const(A_SUB,NR_STACK_POINTER_REG,NR_STACK_POINTER_REG,winstackpagesize));
  714. reference_reset_base(href,NR_STACK_POINTER_REG,0);
  715. { the data stored doesn't matter }
  716. list.concat(Taicpu.op_reg_ref(A_STR,NR_R0,href));
  717. list.concat(Taicpu.op_reg_reg_const(A_SUB,NR_R12,NR_R12,1));
  718. a_jmp_cond(list,OC_NE,again);
  719. if is_shifter_const(localsize mod winstackpagesize,shift) then
  720. list.concat(Taicpu.op_reg_reg_const(A_SUB,NR_STACK_POINTER_REG,NR_STACK_POINTER_REG,localsize mod winstackpagesize))
  721. else
  722. begin
  723. a_load_const_reg(list,OS_ADDR,localsize mod winstackpagesize,NR_R12);
  724. list.concat(taicpu.op_reg_reg_reg(A_SUB,NR_STACK_POINTER_REG,NR_STACK_POINTER_REG,NR_R12));
  725. end;
  726. a_reg_dealloc(list,NR_R12);
  727. reference_reset_base(href,NR_STACK_POINTER_REG,0);
  728. { the data stored doesn't matter }
  729. list.concat(Taicpu.op_reg_ref(A_STR,NR_R0,href));
  730. end
  731. end
  732. else
  733. }
  734. if LocalSize<>0 then
  735. if not(is_shifter_const(localsize,shift)) then
  736. begin
  737. if current_procinfo.framepointer=NR_STACK_POINTER_REG then
  738. a_reg_alloc(list,NR_R12);
  739. a_load_const_reg(list,OS_ADDR,LocalSize,NR_R12);
  740. list.concat(taicpu.op_reg_reg_reg(A_SUB,NR_STACK_POINTER_REG,NR_STACK_POINTER_REG,NR_R12));
  741. a_reg_dealloc(list,NR_R12);
  742. end
  743. else
  744. begin
  745. a_reg_dealloc(list,NR_R12);
  746. list.concat(taicpu.op_reg_reg_const(A_SUB,NR_STACK_POINTER_REG,NR_STACK_POINTER_REG,LocalSize));
  747. end;
  748. if firstfloatreg<>RS_NO then
  749. begin
  750. reference_reset(ref);
  751. if tg.direction*tarmprocinfo(current_procinfo).floatregstart>=1023 then
  752. begin
  753. a_load_const_reg(list,OS_ADDR,-tarmprocinfo(current_procinfo).floatregstart,NR_R12);
  754. list.concat(taicpu.op_reg_reg_reg(A_SUB,NR_R12,current_procinfo.framepointer,NR_R12));
  755. ref.base:=NR_R12;
  756. end
  757. else
  758. begin
  759. ref.base:=current_procinfo.framepointer;
  760. ref.offset:=tarmprocinfo(current_procinfo).floatregstart;
  761. end;
  762. list.concat(taicpu.op_reg_const_ref(A_SFM,newreg(R_FPUREGISTER,firstfloatreg,R_SUBWHOLE),
  763. lastfloatreg-firstfloatreg+1,ref));
  764. end;
  765. end;
  766. }
  767. end;
  768. procedure tcgavr.g_proc_exit(list : TAsmList;parasize : longint;nostackframe:boolean);
  769. {
  770. var
  771. ref : treference;
  772. firstfloatreg,lastfloatreg,
  773. r : byte;
  774. shift : byte;
  775. regs : tcpuregisterset;
  776. LocalSize : longint;
  777. }
  778. begin
  779. internalerror(2011021318);
  780. {
  781. if not(nostackframe) then
  782. begin
  783. { restore floating point register }
  784. firstfloatreg:=RS_NO;
  785. { save floating point registers? }
  786. for r:=RS_F0 to RS_F7 do
  787. if r in rg[R_FPUREGISTER].used_in_proc-paramanager.get_volatile_registers_fpu(pocall_stdcall) then
  788. begin
  789. if firstfloatreg=RS_NO then
  790. firstfloatreg:=r;
  791. lastfloatreg:=r;
  792. end;
  793. if firstfloatreg<>RS_NO then
  794. begin
  795. reference_reset(ref);
  796. if tg.direction*tarmprocinfo(current_procinfo).floatregstart>=1023 then
  797. begin
  798. a_load_const_reg(list,OS_ADDR,-tarmprocinfo(current_procinfo).floatregstart,NR_R12);
  799. list.concat(taicpu.op_reg_reg_reg(A_SUB,NR_R12,current_procinfo.framepointer,NR_R12));
  800. ref.base:=NR_R12;
  801. end
  802. else
  803. begin
  804. ref.base:=current_procinfo.framepointer;
  805. ref.offset:=tarmprocinfo(current_procinfo).floatregstart;
  806. end;
  807. list.concat(taicpu.op_reg_const_ref(A_LFM,newreg(R_FPUREGISTER,firstfloatreg,R_SUBWHOLE),
  808. lastfloatreg-firstfloatreg+1,ref));
  809. end;
  810. if (current_procinfo.framepointer=NR_STACK_POINTER_REG) then
  811. begin
  812. LocalSize:=current_procinfo.calc_stackframe_size;
  813. if LocalSize<>0 then
  814. if not(is_shifter_const(LocalSize,shift)) then
  815. begin
  816. a_reg_alloc(list,NR_R12);
  817. a_load_const_reg(list,OS_ADDR,LocalSize,NR_R12);
  818. list.concat(taicpu.op_reg_reg_reg(A_ADD,NR_STACK_POINTER_REG,NR_STACK_POINTER_REG,NR_R12));
  819. a_reg_dealloc(list,NR_R12);
  820. end
  821. else
  822. begin
  823. list.concat(taicpu.op_reg_reg_const(A_ADD,NR_STACK_POINTER_REG,NR_STACK_POINTER_REG,LocalSize));
  824. end;
  825. regs:=rg[R_INTREGISTER].used_in_proc-paramanager.get_volatile_registers_int(pocall_stdcall);
  826. if (pi_do_call in current_procinfo.flags) or (regs<>[]) then
  827. begin
  828. exclude(regs,RS_R14);
  829. include(regs,RS_R15);
  830. end;
  831. if regs=[] then
  832. list.concat(taicpu.op_reg_reg(A_MOV,NR_R15,NR_R14))
  833. else
  834. begin
  835. reference_reset(ref);
  836. ref.index:=NR_STACK_POINTER_REG;
  837. ref.addressmode:=AM_PREINDEXED;
  838. list.concat(setoppostfix(taicpu.op_ref_regset(A_LDM,ref,regs),PF_FD));
  839. end;
  840. end
  841. else
  842. begin
  843. { restore int registers and return }
  844. reference_reset(ref);
  845. ref.index:=NR_FRAME_POINTER_REG;
  846. list.concat(setoppostfix(taicpu.op_ref_regset(A_LDM,ref,rg[R_INTREGISTER].used_in_proc-paramanager.get_volatile_registers_int(pocall_stdcall)+[RS_R11,RS_R13,RS_R15]),PF_EA));
  847. end;
  848. end
  849. else
  850. list.concat(taicpu.op_reg_reg(A_MOV,NR_PC,NR_R14));
  851. }
  852. end;
  853. procedure tcgavr.a_loadaddr_ref_reg(list : TAsmList;const ref : treference;r : tregister);
  854. begin
  855. internalerror(2011021319);
  856. end;
  857. procedure tcgavr.fixref(list : TAsmList;var ref : treference);
  858. begin
  859. internalerror(2011021320);
  860. end;
  861. procedure tcgavr.g_concatcopy_move(list : TAsmList;const source,dest : treference;len : aint);
  862. var
  863. paraloc1,paraloc2,paraloc3 : TCGPara;
  864. begin
  865. paraloc1.init;
  866. paraloc2.init;
  867. paraloc3.init;
  868. paramanager.getintparaloc(pocall_default,1,paraloc1);
  869. paramanager.getintparaloc(pocall_default,2,paraloc2);
  870. paramanager.getintparaloc(pocall_default,3,paraloc3);
  871. a_load_const_cgpara(list,OS_INT,len,paraloc3);
  872. a_loadaddr_ref_cgpara(list,dest,paraloc2);
  873. a_loadaddr_ref_cgpara(list,source,paraloc1);
  874. paramanager.freecgpara(list,paraloc3);
  875. paramanager.freecgpara(list,paraloc2);
  876. paramanager.freecgpara(list,paraloc1);
  877. alloccpuregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
  878. a_call_name_static(list,'FPC_MOVE');
  879. dealloccpuregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
  880. paraloc3.done;
  881. paraloc2.done;
  882. paraloc1.done;
  883. end;
  884. procedure tcgavr.g_concatcopy_internal(list : TAsmList;const source,dest : treference;len : aint;aligned : boolean);
  885. begin
  886. internalerror(2011021321);
  887. end;
  888. procedure tcgavr.g_concatcopy_unaligned(list : TAsmList;const source,dest : treference;len : aint);
  889. begin
  890. g_concatcopy_internal(list,source,dest,len,false);
  891. end;
  892. procedure tcgavr.g_concatcopy(list : TAsmList;const source,dest : treference;len : aint);
  893. begin
  894. if (source.alignment in [1..3]) or
  895. (dest.alignment in [1..3]) then
  896. g_concatcopy_internal(list,source,dest,len,false)
  897. else
  898. g_concatcopy_internal(list,source,dest,len,true);
  899. end;
  900. procedure tcgavr.g_overflowCheck(list : TAsmList;const l : tlocation;def : tdef);
  901. var
  902. ovloc : tlocation;
  903. begin
  904. ovloc.loc:=LOC_VOID;
  905. g_overflowCheck_loc(list,l,def,ovloc);
  906. end;
  907. procedure tcgavr.g_overflowCheck_loc(List:TAsmList;const Loc:TLocation;def:TDef;ovloc : tlocation);
  908. begin
  909. internalerror(2011021322);
  910. end;
  911. {
  912. procedure tcgavr.g_save_registers(list : TAsmList);
  913. begin
  914. { this work is done in g_proc_entry }
  915. end;
  916. procedure tcgavr.g_restore_registers(list : TAsmList);
  917. begin
  918. { this work is done in g_proc_exit }
  919. end;
  920. }
  921. procedure tcgavr.a_jmp_cond(list : TAsmList;cond : TOpCmp;l: tasmlabel);
  922. var
  923. ai : taicpu;
  924. begin
  925. ai:=Taicpu.Op_sym(A_BRxx,l);
  926. ai.SetCondition(OpCmp2AsmCond[cond]);
  927. ai.is_jmp:=true;
  928. list.concat(ai);
  929. end;
  930. procedure tcgavr.g_intf_wrapper(list: TAsmList; procdef: tprocdef; const labelname: string; ioffset: longint);
  931. begin
  932. internalerror(2011021324);
  933. end;
  934. procedure tcgavr.emit_mov(list: TAsmList;reg2: tregister; reg1: tregister);
  935. var
  936. instr: taicpu;
  937. begin
  938. list.concat(taicpu.op_reg_reg(A_MOV, reg2, reg1));
  939. list.Concat(instr);
  940. { Notify the register allocator that we have written a move instruction so
  941. it can try to eliminate it. }
  942. add_move_instruction(instr);
  943. end;
  944. procedure tcg64favr.a_op64_reg_reg(list : TAsmList;op:TOpCG;size : tcgsize;regsrc,regdst : tregister64);
  945. begin
  946. internalerror(2011021325);
  947. end;
  948. procedure tcg64favr.a_op64_const_reg(list : TAsmList;op:TOpCG;size : tcgsize;value : int64;reg : tregister64);
  949. begin
  950. a_op64_const_reg_reg(list,op,size,value,reg,reg);
  951. end;
  952. procedure tcg64favr.a_op64_const_reg_reg(list: TAsmList;op:TOpCG;size : tcgsize;value : int64;regsrc,regdst : tregister64);
  953. var
  954. ovloc : tlocation;
  955. begin
  956. a_op64_const_reg_reg_checkoverflow(list,op,size,value,regsrc,regdst,false,ovloc);
  957. end;
  958. procedure tcg64favr.a_op64_reg_reg_reg(list: TAsmList;op:TOpCG;size : tcgsize;regsrc1,regsrc2,regdst : tregister64);
  959. var
  960. ovloc : tlocation;
  961. begin
  962. a_op64_reg_reg_reg_checkoverflow(list,op,size,regsrc1,regsrc2,regdst,false,ovloc);
  963. end;
  964. procedure tcg64favr.a_op64_const_reg_reg_checkoverflow(list: TAsmList;op:TOpCG;size : tcgsize;value : int64;regsrc,regdst : tregister64;setflags : boolean;var ovloc : tlocation);
  965. begin
  966. internalerror(2011021326);
  967. end;
  968. procedure tcg64favr.a_op64_reg_reg_reg_checkoverflow(list: TAsmList;op:TOpCG;size : tcgsize;regsrc1,regsrc2,regdst : tregister64;setflags : boolean;var ovloc : tlocation);
  969. begin
  970. internalerror(2011021327);
  971. end;
  972. procedure create_codegen;
  973. begin
  974. cg:=tcgavr.create;
  975. cg64:=tcg64favr.create;
  976. end;
  977. end.