n68kadd.pas 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614
  1. {
  2. Copyright (c) 2000-2002 by Florian Klaempfl and Jonas Maebe
  3. Code generation for add nodes on the Motorola 680x0 family
  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 n68kadd;
  18. {$i fpcdefs.inc}
  19. interface
  20. uses
  21. node,nadd,ncgadd,cpubase,cgbase;
  22. type
  23. t68kaddnode = class(tcgaddnode)
  24. private
  25. function getresflags(unsigned: boolean) : tresflags;
  26. function getfloatresflags: tresflags;
  27. protected
  28. procedure second_addfloat;override;
  29. procedure second_cmpfloat;override;
  30. procedure second_cmpordinal;override;
  31. procedure second_cmpsmallset;override;
  32. procedure second_cmp64bit;override;
  33. end;
  34. implementation
  35. uses
  36. globtype,systems,
  37. cutils,verbose,globals,
  38. symconst,symdef,paramgr,symtype,
  39. aasmbase,aasmtai,aasmdata,aasmcpu,defutil,htypechk,
  40. cpuinfo,pass_1,pass_2,regvars,
  41. cpupara,cgutils,procinfo,
  42. ncon,nset,
  43. ncgutil,tgobj,rgobj,rgcpu,cgobj,cgcpu,hlcgobj,cg64f32;
  44. {*****************************************************************************
  45. Helpers
  46. *****************************************************************************}
  47. function t68kaddnode.getresflags(unsigned : boolean) : tresflags;
  48. begin
  49. case nodetype of
  50. equaln : getresflags:=F_E;
  51. unequaln : getresflags:=F_NE;
  52. else
  53. if not(unsigned) then
  54. begin
  55. if nf_swapped in flags then
  56. case nodetype of
  57. ltn : getresflags:=F_G;
  58. lten : getresflags:=F_GE;
  59. gtn : getresflags:=F_L;
  60. gten : getresflags:=F_LE;
  61. else
  62. internalerror(2014082030);
  63. end
  64. else
  65. case nodetype of
  66. ltn : getresflags:=F_L;
  67. lten : getresflags:=F_LE;
  68. gtn : getresflags:=F_G;
  69. gten : getresflags:=F_GE;
  70. else
  71. internalerror(2014082031);
  72. end;
  73. end
  74. else
  75. begin
  76. if nf_swapped in flags then
  77. case nodetype of
  78. ltn : getresflags:=F_A;
  79. lten : getresflags:=F_AE;
  80. gtn : getresflags:=F_B;
  81. gten : getresflags:=F_BE;
  82. else
  83. internalerror(2014082032);
  84. end
  85. else
  86. case nodetype of
  87. ltn : getresflags:=F_B;
  88. lten : getresflags:=F_BE;
  89. gtn : getresflags:=F_A;
  90. gten : getresflags:=F_AE;
  91. else
  92. internalerror(2014082033);
  93. end;
  94. end;
  95. end;
  96. end;
  97. function t68kaddnode.getfloatresflags : tresflags;
  98. begin
  99. case nodetype of
  100. equaln : getfloatresflags:=F_FE;
  101. unequaln : getfloatresflags:=F_FNE;
  102. else
  103. if nf_swapped in flags then
  104. case nodetype of
  105. ltn : getfloatresflags:=F_FG;
  106. lten : getfloatresflags:=F_FGE;
  107. gtn : getfloatresflags:=F_FL;
  108. gten : getfloatresflags:=F_FLE;
  109. else
  110. internalerror(201604260);
  111. end
  112. else
  113. case nodetype of
  114. ltn : getfloatresflags:=F_FL;
  115. lten : getfloatresflags:=F_FLE;
  116. gtn : getfloatresflags:=F_FG;
  117. gten : getfloatresflags:=F_FGE;
  118. else
  119. internalerror(201604261);
  120. end;
  121. end;
  122. end;
  123. {*****************************************************************************
  124. AddFloat
  125. *****************************************************************************}
  126. procedure t68kaddnode.second_addfloat;
  127. var
  128. op : TAsmOp;
  129. href : TReference;
  130. begin
  131. pass_left_right;
  132. case nodetype of
  133. addn :
  134. op:=A_FADD;
  135. muln :
  136. op:=A_FMUL;
  137. subn :
  138. op:=A_FSUB;
  139. slashn :
  140. op:=A_FDIV;
  141. else
  142. internalerror(200403182);
  143. end;
  144. // get the operands in the correct order, there are no special cases
  145. // here, everything is register-based
  146. if nf_swapped in flags then
  147. swapleftright;
  148. case current_settings.fputype of
  149. fpu_68881,fpu_coldfire:
  150. begin
  151. { initialize the result }
  152. location_reset(location,LOC_FPUREGISTER,def_cgsize(resultdef));
  153. { have left in the register, right can be a memory location }
  154. if not (current_settings.fputype = fpu_coldfire) and
  155. (left.nodetype = realconstn) then
  156. begin
  157. location.register := cg.getfpuregister(current_asmdata.CurrAsmList,location.size);
  158. current_asmdata.CurrAsmList.concat(taicpu.op_realconst_reg(A_FMOVE,tcgsize2opsize[left.location.size],trealconstnode(left).value_real,location.register))
  159. end
  160. else
  161. begin
  162. hlcg.location_force_fpureg(current_asmdata.CurrAsmList,left.location,left.resultdef,true);
  163. location.register := cg.getfpuregister(current_asmdata.CurrAsmList,location.size);
  164. cg.a_loadfpu_reg_reg(current_asmdata.CurrAsmlist,OS_NO,OS_NO,left.location.register,location.register);
  165. end;
  166. { emit the actual operation }
  167. case right.location.loc of
  168. LOC_FPUREGISTER,LOC_CFPUREGISTER:
  169. current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(op,fpuregopsize,right.location.register,location.register));
  170. LOC_REFERENCE,LOC_CREFERENCE:
  171. begin
  172. if not (current_settings.fputype = fpu_coldfire) and
  173. (right.nodetype = realconstn) then
  174. current_asmdata.CurrAsmList.concat(taicpu.op_realconst_reg(op,tcgsize2opsize[right.location.size],trealconstnode(right).value_real,location.register))
  175. else
  176. begin
  177. href:=right.location.reference;
  178. tcg68k(cg).fixref(current_asmdata.CurrAsmList,href,current_settings.fputype = fpu_coldfire);
  179. current_asmdata.CurrAsmList.concat(taicpu.op_ref_reg(op,tcgsize2opsize[right.location.size],href,location.register));
  180. end;
  181. end
  182. else
  183. internalerror(2015021501);
  184. end;
  185. end;
  186. else
  187. // softfpu should be handled in pass1, others are not yet supported...
  188. internalerror(2015010201);
  189. end;
  190. end;
  191. procedure t68kaddnode.second_cmpfloat;
  192. var
  193. tmpreg : tregister;
  194. ai: taicpu;
  195. href : TReference;
  196. begin
  197. pass_left_right;
  198. if (nf_swapped in flags) then
  199. swapleftright;
  200. case current_settings.fputype of
  201. fpu_68881,fpu_coldfire:
  202. begin
  203. { force left fpureg as register, right can be reference }
  204. { emit compare }
  205. case right.location.loc of
  206. LOC_FPUREGISTER,LOC_CFPUREGISTER:
  207. begin
  208. hlcg.location_force_fpureg(current_asmdata.CurrAsmList,left.location,left.resultdef,true);
  209. current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_FCMP,fpuregopsize,right.location.register,left.location.register));
  210. end;
  211. LOC_REFERENCE,LOC_CREFERENCE:
  212. begin
  213. { use FTST, if realconst is 0.0, it would be very had to do this in the
  214. optimized, because we would need to investigate the referenced value... }
  215. if (right.nodetype = realconstn) and
  216. (trealconstnode(right).value_real = 0.0) then
  217. begin
  218. if left.location.loc in [LOC_FPUREGISTER,LOC_CFPUREGISTER] then
  219. current_asmdata.CurrAsmList.concat(taicpu.op_reg(A_FTST,fpuregopsize,left.location.register))
  220. else
  221. if left.location.loc in [LOC_REFERENCE,LOC_CREFERENCE] then
  222. begin
  223. href:=left.location.reference;
  224. tcg68k(cg).fixref(current_asmdata.CurrAsmList,href,false);
  225. current_asmdata.CurrAsmList.concat(taicpu.op_ref(A_FTST,tcgsize2opsize[left.location.size],href))
  226. end
  227. else
  228. internalerror(2016051001);
  229. end
  230. else
  231. begin
  232. hlcg.location_force_fpureg(current_asmdata.CurrAsmList,left.location,left.resultdef,true);
  233. if not (current_settings.fputype = fpu_coldfire) and
  234. (right.nodetype = realconstn) then
  235. current_asmdata.CurrAsmList.concat(taicpu.op_realconst_reg(A_FCMP,tcgsize2opsize[right.location.size],trealconstnode(right).value_real,left.location.register))
  236. else
  237. begin
  238. href:=right.location.reference;
  239. tcg68k(cg).fixref(current_asmdata.CurrAsmList,href,current_settings.fputype = fpu_coldfire);
  240. current_asmdata.CurrAsmList.concat(taicpu.op_ref_reg(A_FCMP,tcgsize2opsize[right.location.size],href,left.location.register));
  241. end;
  242. end;
  243. end
  244. else
  245. internalerror(2015021502);
  246. end;
  247. location_reset(location,LOC_FLAGS,OS_NO);
  248. location.resflags:=getfloatresflags;
  249. end;
  250. else
  251. // softfpu should be handled in pass1, others are not yet supported...
  252. internalerror(2015010201);
  253. end;
  254. end;
  255. {*****************************************************************************
  256. Smallsets
  257. *****************************************************************************}
  258. procedure t68kaddnode.second_cmpsmallset;
  259. var
  260. tmpreg : tregister;
  261. begin
  262. pass_left_right;
  263. location_reset(location,LOC_FLAGS,OS_NO);
  264. if (not(nf_swapped in flags) and
  265. (nodetype = lten)) or
  266. ((nf_swapped in flags) and
  267. (nodetype = gten)) then
  268. swapleftright;
  269. { Try to keep right as a constant }
  270. if right.location.loc<>LOC_CONSTANT then
  271. hlcg.location_force_reg(current_asmdata.CurrAsmList,right.location,right.resultdef,right.resultdef,true);
  272. hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,left.resultdef,true);
  273. case nodetype of
  274. equaln,
  275. unequaln:
  276. begin
  277. if right.location.loc=LOC_CONSTANT then
  278. current_asmdata.CurrAsmList.concat(taicpu.op_const_reg(A_CMP,S_L,right.location.value,left.location.register))
  279. else
  280. current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_CMP,S_L,right.location.register,left.location.register));
  281. if nodetype=equaln then
  282. location.resflags:=F_E
  283. else
  284. location.resflags:=F_NE;
  285. end;
  286. lten,
  287. gten:
  288. begin
  289. tmpreg:=cg.getintregister(current_asmdata.CurrAsmList,left.location.size);
  290. if right.location.loc=LOC_CONSTANT then
  291. hlcg.location_force_reg(current_asmdata.CurrAsmList,right.location,right.resultdef,right.resultdef,false);
  292. cg.a_op_reg_reg_reg(current_asmdata.CurrAsmList,OP_AND,OS_32,left.location.register,right.location.register,tmpreg);
  293. current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_CMP,S_L,tmpreg,right.location.register));
  294. location.resflags:=F_E;
  295. end;
  296. else
  297. internalerror(2013092701);
  298. end;
  299. end;
  300. {*****************************************************************************
  301. Ordinals
  302. *****************************************************************************}
  303. procedure t68kaddnode.second_cmpordinal;
  304. var
  305. unsigned : boolean;
  306. tmpreg : tregister;
  307. opsize : topsize;
  308. cmpsize : tcgsize;
  309. href: treference;
  310. begin
  311. { determine if the comparison will be unsigned }
  312. unsigned:=not(is_signed(left.resultdef)) or
  313. not(is_signed(right.resultdef));
  314. { this puts constant operand (if any) to the right }
  315. pass_left_right;
  316. { tentatively assume left size (correct for possible TST, will fix later) }
  317. cmpsize:=def_cgsize(left.resultdef);
  318. opsize:=tcgsize2opsize[cmpsize];
  319. { set result location }
  320. location_reset(location,LOC_FLAGS,OS_NO);
  321. { see if we can optimize into TST }
  322. if (right.location.loc=LOC_CONSTANT) and (right.location.value=0) then
  323. begin
  324. { Unsigned <0 or >=0 should not reach pass2, most likely }
  325. case left.location.loc of
  326. LOC_REFERENCE,
  327. LOC_CREFERENCE:
  328. begin
  329. href:=left.location.reference;
  330. tcg68k(cg).fixref(current_asmdata.CurrAsmList,href,false);
  331. current_asmdata.CurrAsmList.concat(taicpu.op_ref(A_TST,opsize,href));
  332. location_freetemp(current_asmdata.CurrAsmList,left.location);
  333. end;
  334. else
  335. hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,left.resultdef,true);
  336. current_asmdata.CurrAsmList.concat(taicpu.op_reg(A_TST,opsize,left.location.register));
  337. end;
  338. location.resflags := getresflags(unsigned);
  339. exit;
  340. end;
  341. { Coldfire supports byte/word compares only starting with ISA_B,
  342. !!see remark about Qemu weirdness in tcg68k.a_cmp_const_reg_label }
  343. if (opsize<>S_L) and (current_settings.cputype in cpu_coldfire{-[cpu_isa_b,cpu_isa_c,cfv4e]}) then
  344. begin
  345. { 1) Extension is needed for LOC_REFERENCE, but what about LOC_REGISTER ? Perhaps after fixing cg we can assume
  346. that high bits of registers are correct.
  347. 2) Assuming that extension depends only on source signedness --> destination OS_32 is acceptable. }
  348. hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,cgsize_orddef(OS_32),false);
  349. if (right.location.loc<>LOC_CONSTANT) then
  350. hlcg.location_force_reg(current_asmdata.CurrAsmList,right.location,right.resultdef,cgsize_orddef(OS_32),false);
  351. opsize:=S_L;
  352. end
  353. else if not (left.location.loc in [LOC_REGISTER,LOC_CREGISTER]) then
  354. begin
  355. if not (right.location.loc in [LOC_REGISTER,LOC_CREGISTER]) then
  356. hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,left.resultdef,true)
  357. else
  358. begin
  359. location_swap(left.location,right.location);
  360. toggleflag(nf_swapped);
  361. end;
  362. end;
  363. { left is now in register }
  364. case right.location.loc of
  365. LOC_CONSTANT:
  366. current_asmdata.CurrAsmList.concat(taicpu.op_const_reg(A_CMP,opsize,
  367. longint(right.location.value),left.location.register));
  368. LOC_REFERENCE,
  369. LOC_CREFERENCE:
  370. begin
  371. href:=right.location.reference;
  372. tcg68k(cg).fixref(current_asmdata.CurrAsmList,href,false);
  373. current_asmdata.CurrAsmList.concat(taicpu.op_ref_reg(A_CMP,opsize,href,
  374. left.location.register));
  375. end;
  376. LOC_REGISTER,
  377. LOC_CREGISTER:
  378. current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_CMP,opsize,
  379. right.location.register,left.location.register));
  380. else
  381. hlcg.location_force_reg(current_asmdata.CurrAsmList,right.location,right.resultdef,right.resultdef,true);
  382. current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_CMP,opsize,
  383. right.location.register,left.location.register));
  384. end;
  385. { update location because sides could have been swapped }
  386. location.resflags:=getresflags(unsigned);
  387. end;
  388. {*****************************************************************************
  389. 64-bit
  390. *****************************************************************************}
  391. procedure t68kaddnode.second_cmp64bit;
  392. var
  393. truelabel,
  394. falselabel: tasmlabel;
  395. hlab: tasmlabel;
  396. unsigned : boolean;
  397. href: treference;
  398. procedure firstjmp64bitcmp;
  399. var
  400. oldnodetype : tnodetype;
  401. begin
  402. case nodetype of
  403. ltn,gtn:
  404. begin
  405. if (hlab<>location.truelabel) then
  406. cg.a_jmp_flags(current_asmdata.CurrAsmList,getresflags(unsigned),location.truelabel);
  407. { cheat a little bit for the negative test }
  408. toggleflag(nf_swapped);
  409. if (hlab<>location.falselabel) then
  410. cg.a_jmp_flags(current_asmdata.CurrAsmList,getresflags(unsigned),location.falselabel);
  411. toggleflag(nf_swapped);
  412. end;
  413. lten,gten:
  414. begin
  415. oldnodetype:=nodetype;
  416. if nodetype=lten then
  417. nodetype:=ltn
  418. else
  419. nodetype:=gtn;
  420. if (hlab<>location.truelabel) then
  421. cg.a_jmp_flags(current_asmdata.CurrAsmList,getresflags(unsigned),location.truelabel);
  422. { cheat for the negative test }
  423. if nodetype=ltn then
  424. nodetype:=gtn
  425. else
  426. nodetype:=ltn;
  427. if (hlab<>location.falselabel) then
  428. cg.a_jmp_flags(current_asmdata.CurrAsmList,getresflags(unsigned),location.falselabel);
  429. nodetype:=oldnodetype;
  430. end;
  431. equaln:
  432. cg.a_jmp_flags(current_asmdata.CurrAsmList,F_NE,location.falselabel);
  433. unequaln:
  434. cg.a_jmp_flags(current_asmdata.CurrAsmList,F_NE,location.truelabel);
  435. end;
  436. end;
  437. procedure secondjmp64bitcmp;
  438. begin
  439. case nodetype of
  440. ltn,gtn,lten,gten:
  441. begin
  442. cg.a_jmp_flags(current_asmdata.CurrAsmList,getresflags(true),location.truelabel);
  443. cg.a_jmp_always(current_asmdata.CurrAsmList,location.falselabel);
  444. end;
  445. equaln:
  446. begin
  447. cg.a_jmp_flags(current_asmdata.CurrAsmList,F_NE,location.falselabel);
  448. cg.a_jmp_always(current_asmdata.CurrAsmList,location.truelabel);
  449. end;
  450. unequaln:
  451. begin
  452. cg.a_jmp_flags(current_asmdata.CurrAsmList,F_NE,location.truelabel);
  453. cg.a_jmp_always(current_asmdata.CurrAsmList,location.falselabel);
  454. end;
  455. end;
  456. end;
  457. begin
  458. truelabel:=nil;
  459. falselabel:=nil;
  460. { This puts constant operand (if any) to the right }
  461. pass_left_right;
  462. unsigned:=not(is_signed(left.resultdef)) or
  463. not(is_signed(right.resultdef));
  464. current_asmdata.getjumplabel(truelabel);
  465. current_asmdata.getjumplabel(falselabel);
  466. location_reset_jump(location,truelabel,falselabel);
  467. { Relational compares against constants having low dword=0 can omit the
  468. second compare based on the fact that any unsigned value is >=0 }
  469. hlab:=nil;
  470. if (right.location.loc=LOC_CONSTANT) and
  471. (lo(right.location.value64)=0) then
  472. begin
  473. case getresflags(true) of
  474. F_AE: hlab:=location.truelabel;
  475. F_B: hlab:=location.falselabel;
  476. end;
  477. end;
  478. if (right.location.loc=LOC_CONSTANT) and (right.location.value64=0) and
  479. (nodetype in [equaln,unequaln]) then
  480. begin
  481. case left.location.loc of
  482. LOC_REFERENCE,
  483. LOC_CREFERENCE:
  484. begin
  485. href:=left.location.reference;
  486. tcg68k(cg).fixref(current_asmdata.CurrAsmList,href,false);
  487. current_asmdata.CurrAsmList.concat(taicpu.op_ref(A_TST,S_L,href));
  488. firstjmp64bitcmp;
  489. inc(href.offset,4);
  490. current_asmdata.CurrAsmList.concat(taicpu.op_ref(A_TST,S_L,href));
  491. secondjmp64bitcmp;
  492. location_freetemp(current_asmdata.CurrAsmList,left.location);
  493. end;
  494. else
  495. hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,left.resultdef,true);
  496. current_asmdata.CurrAsmList.concat(taicpu.op_reg(A_TST,S_L,left.location.register64.reglo));
  497. firstjmp64bitcmp;
  498. current_asmdata.CurrAsmList.concat(taicpu.op_reg(A_TST,S_L,left.location.register64.reghi));
  499. secondjmp64bitcmp;
  500. end;
  501. exit;
  502. end;
  503. { left and right no register? }
  504. { then one must be demanded }
  505. if not (left.location.loc in [LOC_REGISTER,LOC_CREGISTER]) then
  506. begin
  507. if not (right.location.loc in [LOC_REGISTER,LOC_CREGISTER]) then
  508. hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,left.resultdef,true)
  509. else
  510. begin
  511. location_swap(left.location,right.location);
  512. toggleflag(nf_swapped);
  513. end;
  514. end;
  515. { left is now in register }
  516. case right.location.loc of
  517. LOC_REGISTER,LOC_CREGISTER:
  518. begin
  519. current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_CMP,S_L,right.location.register64.reghi,left.location.register64.reghi));
  520. firstjmp64bitcmp;
  521. current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_CMP,S_L,right.location.register64.reglo,left.location.register64.reglo));
  522. secondjmp64bitcmp;
  523. end;
  524. LOC_REFERENCE,LOC_CREFERENCE:
  525. begin
  526. href:=right.location.reference;
  527. tcg68k(cg).fixref(current_asmdata.CurrAsmList,href,false);
  528. current_asmdata.CurrAsmList.concat(taicpu.op_ref_reg(A_CMP,S_L,href,left.location.register64.reghi));
  529. firstjmp64bitcmp;
  530. inc(href.offset,4);
  531. current_asmdata.CurrAsmList.concat(taicpu.op_ref_reg(A_CMP,S_L,href,left.location.register64.reglo));
  532. secondjmp64bitcmp;
  533. location_freetemp(current_asmdata.CurrAsmList,right.location);
  534. end;
  535. LOC_CONSTANT:
  536. begin
  537. current_asmdata.CurrAsmList.concat(taicpu.op_const_reg(A_CMP,S_L,aint(hi(right.location.value64)),left.location.register64.reghi));
  538. firstjmp64bitcmp;
  539. if assigned(hlab) then
  540. cg.a_jmp_always(current_asmdata.CurrAsmList,hlab)
  541. else
  542. begin
  543. current_asmdata.CurrAsmList.concat(taicpu.op_const_reg(A_CMP,S_L,aint(lo(right.location.value64)),left.location.register64.reglo));
  544. secondjmp64bitcmp;
  545. end;
  546. end;
  547. else
  548. InternalError(2014072501);
  549. end;
  550. end;
  551. begin
  552. caddnode:=t68kaddnode;
  553. end.