nz80add.pas 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667
  1. {
  2. Copyright (c) 2008 by Florian Klaempfl
  3. Code generation for add nodes on the AVR
  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 nz80add;
  18. {$i fpcdefs.inc}
  19. interface
  20. uses
  21. node,ncgadd, symtype,cpubase;
  22. type
  23. { TZ80AddNode }
  24. TZ80AddNode = class(tcgaddnode)
  25. private
  26. function GetResFlags(unsigned:Boolean;anodetype:tnodetype):TResFlags;
  27. protected
  28. function use_mul_helper: boolean;override;
  29. function first_cmppointer: tnode;override;
  30. function pass_1 : tnode;override;
  31. procedure second_cmpordinal;override;
  32. procedure second_cmpsmallset;override;
  33. procedure second_cmp64bit;override;
  34. procedure second_cmp16_32_64bit;
  35. procedure second_cmp;
  36. end;
  37. implementation
  38. uses
  39. globtype,systems,
  40. cutils,verbose,globals,
  41. symconst,symdef,paramgr,
  42. aasmbase,aasmtai,aasmdata,aasmcpu,defutil,htypechk,
  43. cgbase,cgutils,cgcpu,
  44. cpuinfo,pass_1,pass_2,procinfo,
  45. cpupara,
  46. ncon,nset,nadd,
  47. ncgutil,tgobj,rgobj,rgcpu,cgobj,cg64f32,
  48. hlcgobj;
  49. {*****************************************************************************
  50. TZ80AddNode
  51. *****************************************************************************}
  52. function TZ80AddNode.GetResFlags(unsigned: Boolean; anodetype: tnodetype): TResFlags;
  53. begin
  54. case anodetype of
  55. equaln:
  56. GetResFlags:=F_E;
  57. unequaln:
  58. GetResFlags:=F_NE;
  59. else
  60. if not(unsigned) then
  61. begin
  62. { signed }
  63. if nf_swapped in flags then
  64. case anodetype of
  65. ltn:
  66. GetResFlags:=F_NotPossible;
  67. lten:
  68. GetResFlags:=F_P;
  69. gtn:
  70. GetResFlags:=F_M;
  71. gten:
  72. GetResFlags:=F_NotPossible;
  73. else
  74. internalerror(2014082020);
  75. end
  76. else
  77. case anodetype of
  78. ltn:
  79. GetResFlags:=F_M;
  80. lten:
  81. GetResFlags:=F_NotPossible;
  82. gtn:
  83. GetResFlags:=F_NotPossible;
  84. gten:
  85. GetResFlags:=F_P;
  86. else
  87. internalerror(2014082021);
  88. end;
  89. end
  90. else
  91. begin
  92. { unsigned }
  93. if nf_swapped in Flags then
  94. case anodetype of
  95. ltn:
  96. GetResFlags:=F_NotPossible;
  97. lten:
  98. GetResFlags:=F_NC;
  99. gtn:
  100. GetResFlags:=F_C;
  101. gten:
  102. GetResFlags:=F_NotPossible;
  103. else
  104. internalerror(2014082022);
  105. end
  106. else
  107. case anodetype of
  108. ltn:
  109. GetResFlags:=F_C;
  110. lten:
  111. GetResFlags:=F_NotPossible;
  112. gtn:
  113. GetResFlags:=F_NotPossible;
  114. gten:
  115. GetResFlags:=F_NC;
  116. else
  117. internalerror(2014082023);
  118. end;
  119. end;
  120. end;
  121. end;
  122. function TZ80AddNode.use_mul_helper: boolean;
  123. begin
  124. result:=(nodetype=muln);
  125. end;
  126. function TZ80AddNode.first_cmppointer: tnode;
  127. begin
  128. result:=nil;
  129. expectloc:=LOC_JUMP;
  130. end;
  131. procedure TZ80AddNode.second_cmpsmallset;
  132. procedure gencmp(tmpreg1,tmpreg2 : tregister);
  133. var
  134. i : byte;
  135. begin
  136. //current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_CP,tmpreg1,tmpreg2));
  137. //for i:=2 to tcgsize2size[left.location.size] do
  138. // begin
  139. // tmpreg1:=GetNextReg(tmpreg1);
  140. // tmpreg2:=GetNextReg(tmpreg2);
  141. // current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_CPC,tmpreg1,tmpreg2));
  142. // end;
  143. end;
  144. var
  145. tmpreg : tregister;
  146. begin
  147. //pass_left_right;
  148. //location_reset(location,LOC_FLAGS,OS_NO);
  149. //force_reg_left_right(false,false);
  150. //
  151. //case nodetype of
  152. // equaln:
  153. // begin
  154. // gencmp(left.location.register,right.location.register);
  155. // location.resflags:=F_EQ;
  156. // end;
  157. // unequaln:
  158. // begin
  159. // gencmp(left.location.register,right.location.register);
  160. // location.resflags:=F_NE;
  161. // end;
  162. // lten,
  163. // gten:
  164. // begin
  165. // if (not(nf_swapped in flags) and
  166. // (nodetype = lten)) or
  167. // ((nf_swapped in flags) and
  168. // (nodetype = gten)) then
  169. // swapleftright;
  170. // tmpreg:=cg.getintregister(current_asmdata.CurrAsmList,location.size);
  171. // cg.a_op_reg_reg_reg(current_asmdata.CurrAsmList,OP_AND,location.size,
  172. // left.location.register,right.location.register,tmpreg);
  173. // gencmp(tmpreg,right.location.register);
  174. // location.resflags:=F_EQ;
  175. // end;
  176. // else
  177. // internalerror(2004012401);
  178. //end;
  179. end;
  180. procedure TZ80AddNode.second_cmp;
  181. var
  182. unsigned : boolean;
  183. tmpreg1,tmpreg2 : tregister;
  184. i : longint;
  185. opdef: tdef;
  186. opsize: TCgSize;
  187. l: TAsmLabel;
  188. begin
  189. unsigned:=not(is_signed(left.resultdef)) or
  190. not(is_signed(right.resultdef));
  191. opdef:=left.resultdef;
  192. opsize:=def_cgsize(opdef);
  193. pass_left_right;
  194. if (opsize=OS_8) or ((opsize=OS_S8) and (NodeType in [equaln,unequaln])) then
  195. begin
  196. if getresflags(unsigned,NodeType)=F_NotPossible then
  197. swapleftright;
  198. if left.location.loc<>LOC_REGISTER then
  199. hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,left.resultdef,false);
  200. if right.location.loc in [LOC_REFERENCE,LOC_CREFERENCE] then
  201. begin
  202. if is_ref_in_opertypes(right.location.reference,[OT_REF_IX_d,OT_REF_IY_d,OT_REF_HL]) then
  203. begin
  204. cg.getcpuregister(current_asmdata.CurrAsmList,NR_A);
  205. cg.a_load_loc_reg(current_asmdata.CurrAsmList,def_cgsize(left.resultdef),left.location,NR_A);
  206. current_asmdata.CurrAsmList.Concat(taicpu.op_reg_ref(A_CP,NR_A,right.location.reference));
  207. cg.ungetcpuregister(current_asmdata.CurrAsmList,NR_A);
  208. end
  209. else
  210. hlcg.location_force_reg(current_asmdata.CurrAsmList,right.location,right.resultdef,right.resultdef,false);
  211. end;
  212. case right.location.loc of
  213. LOC_CONSTANT:
  214. begin
  215. cg.getcpuregister(current_asmdata.CurrAsmList,NR_A);
  216. cg.a_load_loc_reg(current_asmdata.CurrAsmList,def_cgsize(left.resultdef),left.location,NR_A);
  217. current_asmdata.CurrAsmList.Concat(taicpu.op_reg_const(A_CP,NR_A,right.location.value));
  218. cg.ungetcpuregister(current_asmdata.CurrAsmList,NR_A);
  219. end;
  220. LOC_REGISTER,LOC_CREGISTER:
  221. begin
  222. cg.getcpuregister(current_asmdata.CurrAsmList,NR_A);
  223. cg.a_load_loc_reg(current_asmdata.CurrAsmList,def_cgsize(left.resultdef),left.location,NR_A);
  224. current_asmdata.CurrAsmList.Concat(taicpu.op_reg_reg(A_CP,NR_A,right.location.register));
  225. cg.ungetcpuregister(current_asmdata.CurrAsmList,NR_A);
  226. end;
  227. LOC_REFERENCE,LOC_CREFERENCE:
  228. begin
  229. { Already handled before the case statement. Nothing to do here. }
  230. end;
  231. else
  232. internalerror(2020040402);
  233. end;
  234. location_reset(location,LOC_FLAGS,OS_NO);
  235. location.resflags:=getresflags(unsigned,NodeType);
  236. end
  237. else if opsize=OS_S8 then
  238. begin
  239. if getresflags(unsigned,NodeType)=F_NotPossible then
  240. swapleftright;
  241. if left.location.loc<>LOC_REGISTER then
  242. hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,left.resultdef,false);
  243. if right.location.loc in [LOC_REFERENCE,LOC_CREFERENCE] then
  244. begin
  245. if is_ref_in_opertypes(right.location.reference,[OT_REF_IX_d,OT_REF_IY_d,OT_REF_HL]) then
  246. begin
  247. cg.getcpuregister(current_asmdata.CurrAsmList,NR_A);
  248. cg.a_load_loc_reg(current_asmdata.CurrAsmList,def_cgsize(left.resultdef),left.location,NR_A);
  249. current_asmdata.CurrAsmList.Concat(taicpu.op_reg_ref(A_SUB,NR_A,right.location.reference));
  250. end
  251. else
  252. hlcg.location_force_reg(current_asmdata.CurrAsmList,right.location,right.resultdef,right.resultdef,false);
  253. end;
  254. case right.location.loc of
  255. LOC_CONSTANT:
  256. begin
  257. cg.getcpuregister(current_asmdata.CurrAsmList,NR_A);
  258. cg.a_load_loc_reg(current_asmdata.CurrAsmList,def_cgsize(left.resultdef),left.location,NR_A);
  259. current_asmdata.CurrAsmList.Concat(taicpu.op_reg_const(A_SUB,NR_A,right.location.value));
  260. end;
  261. LOC_REGISTER,LOC_CREGISTER:
  262. begin
  263. cg.getcpuregister(current_asmdata.CurrAsmList,NR_A);
  264. cg.a_load_loc_reg(current_asmdata.CurrAsmList,def_cgsize(left.resultdef),left.location,NR_A);
  265. current_asmdata.CurrAsmList.Concat(taicpu.op_reg_reg(A_SUB,NR_A,right.location.register));
  266. end;
  267. LOC_REFERENCE,LOC_CREFERENCE:
  268. begin
  269. { Already handled before the case statement. Nothing to do here. }
  270. end;
  271. else
  272. internalerror(2020040403);
  273. end;
  274. current_asmdata.getjumplabel(l);
  275. cg.a_jmp_flags(current_asmdata.CurrAsmList,F_PO,l);
  276. current_asmdata.CurrAsmList.Concat(taicpu.op_reg_const(A_XOR,NR_A,$80));
  277. cg.a_label(current_asmdata.CurrAsmList,l);
  278. cg.ungetcpuregister(current_asmdata.CurrAsmList,NR_A);
  279. location_reset(location,LOC_FLAGS,OS_NO);
  280. location.resflags:=getresflags(unsigned,NodeType);
  281. end
  282. else
  283. internalerror(2020040401);
  284. end;
  285. procedure TZ80AddNode.second_cmp64bit;
  286. begin
  287. second_cmp16_32_64bit;
  288. end;
  289. procedure TZ80AddNode.second_cmp16_32_64bit;
  290. var
  291. truelabel,
  292. falselabel: tasmlabel;
  293. unsigned : boolean;
  294. i, size: Integer;
  295. tmpref: treference;
  296. op: TAsmOp;
  297. actualnodetype: tnodetype;
  298. begin
  299. truelabel:=nil;
  300. falselabel:=nil;
  301. pass_left_right;
  302. unsigned:=not(is_signed(left.resultdef)) or
  303. not(is_signed(right.resultdef));
  304. { we have LOC_JUMP as result }
  305. current_asmdata.getjumplabel(truelabel);
  306. current_asmdata.getjumplabel(falselabel);
  307. location_reset_jump(location,truelabel,falselabel);
  308. size:=tcgsize2size[def_cgsize(left.resultdef)];
  309. if NodeType in [equaln,unequaln] then
  310. begin
  311. if left.location.loc<>LOC_REGISTER then
  312. hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,left.resultdef,false);
  313. if right.location.loc in [LOC_REFERENCE,LOC_CREFERENCE] then
  314. begin
  315. if is_ref_in_opertypes(right.location.reference,[OT_REF_IX_d,OT_REF_IY_d,OT_REF_HL]) then
  316. begin
  317. cg.getcpuregister(current_asmdata.CurrAsmList,NR_A);
  318. tmpref:=right.location.reference;
  319. for i:=0 to size-1 do
  320. begin
  321. cg.a_load_reg_reg(current_asmdata.CurrAsmList,OS_8,OS_8,tcgz80(cg).GetOffsetReg64(left.location.register,left.location.registerhi,i),NR_A);
  322. current_asmdata.CurrAsmList.Concat(taicpu.op_reg_ref(A_CP,NR_A,tmpref));
  323. case NodeType of
  324. equaln:
  325. if i<>(size-1) then
  326. cg.a_jmp_flags(current_asmdata.CurrAsmList,F_NE,falselabel)
  327. else
  328. cg.a_jmp_flags(current_asmdata.CurrAsmList,F_E,truelabel);
  329. unequaln:
  330. cg.a_jmp_flags(current_asmdata.CurrAsmList,F_NE,truelabel);
  331. else
  332. internalerror(2020042102);
  333. end;
  334. if i<>(size-1) then
  335. tcgz80(cg).adjust_normalized_ref(current_asmdata.CurrAsmList,tmpref,1);
  336. end;
  337. cg.ungetcpuregister(current_asmdata.CurrAsmList,NR_A);
  338. cg.a_jmp_always(current_asmdata.CurrAsmList,falselabel);
  339. end
  340. else
  341. hlcg.location_force_reg(current_asmdata.CurrAsmList,right.location,right.resultdef,right.resultdef,false);
  342. end;
  343. case right.location.loc of
  344. LOC_CONSTANT:
  345. begin
  346. cg.getcpuregister(current_asmdata.CurrAsmList,NR_A);
  347. for i:=0 to size-1 do
  348. begin
  349. cg.a_load_reg_reg(current_asmdata.CurrAsmList,OS_8,OS_8,tcgz80(cg).GetOffsetReg64(left.location.register,left.location.registerhi,i),NR_A);
  350. current_asmdata.CurrAsmList.Concat(taicpu.op_reg_const(A_CP,NR_A,byte(right.location.value shr (i*8))));
  351. case NodeType of
  352. equaln:
  353. if i<>(size-1) then
  354. cg.a_jmp_flags(current_asmdata.CurrAsmList,F_NE,falselabel)
  355. else
  356. cg.a_jmp_flags(current_asmdata.CurrAsmList,F_E,truelabel);
  357. unequaln:
  358. cg.a_jmp_flags(current_asmdata.CurrAsmList,F_NE,truelabel);
  359. else
  360. internalerror(2020042104);
  361. end;
  362. end;
  363. cg.ungetcpuregister(current_asmdata.CurrAsmList,NR_A);
  364. cg.a_jmp_always(current_asmdata.CurrAsmList,falselabel);
  365. end;
  366. LOC_REGISTER,LOC_CREGISTER:
  367. begin
  368. cg.getcpuregister(current_asmdata.CurrAsmList,NR_A);
  369. for i:=0 to size-1 do
  370. begin
  371. cg.a_load_reg_reg(current_asmdata.CurrAsmList,OS_8,OS_8,tcgz80(cg).GetOffsetReg64(left.location.register,left.location.registerhi,i),NR_A);
  372. current_asmdata.CurrAsmList.Concat(taicpu.op_reg_reg(A_CP,NR_A,tcgz80(cg).GetOffsetReg64(right.location.register,right.location.registerhi,i)));
  373. case NodeType of
  374. equaln:
  375. if i<>(size-1) then
  376. cg.a_jmp_flags(current_asmdata.CurrAsmList,F_NE,falselabel)
  377. else
  378. cg.a_jmp_flags(current_asmdata.CurrAsmList,F_E,truelabel);
  379. unequaln:
  380. cg.a_jmp_flags(current_asmdata.CurrAsmList,F_NE,truelabel);
  381. else
  382. internalerror(2020042105);
  383. end;
  384. end;
  385. cg.ungetcpuregister(current_asmdata.CurrAsmList,NR_A);
  386. cg.a_jmp_always(current_asmdata.CurrAsmList,falselabel);
  387. end;
  388. LOC_REFERENCE,LOC_CREFERENCE:
  389. begin
  390. { Already handled before the case statement. Nothing to do here. }
  391. end;
  392. else
  393. internalerror(2020042103);
  394. end;
  395. end
  396. else
  397. begin
  398. if nf_swapped in Flags then
  399. begin
  400. case NodeType of
  401. ltn:
  402. actualnodetype:=gtn;
  403. lten:
  404. actualnodetype:=gten;
  405. gtn:
  406. actualnodetype:=ltn;
  407. gten:
  408. actualnodetype:=lten;
  409. else
  410. internalerror(2020042701);
  411. end;
  412. end
  413. else
  414. actualnodetype:=NodeType;
  415. if left.location.loc<>LOC_REGISTER then
  416. hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,left.resultdef,false);
  417. if right.location.loc in [LOC_REFERENCE,LOC_CREFERENCE] then
  418. begin
  419. if is_ref_in_opertypes(right.location.reference,[OT_REF_IX_d,OT_REF_IY_d,OT_REF_HL]) then
  420. begin
  421. cg.getcpuregister(current_asmdata.CurrAsmList,NR_A);
  422. tmpref:=right.location.reference;
  423. tcgz80(cg).adjust_normalized_ref(current_asmdata.CurrAsmList,tmpref,size-1);
  424. for i:=size-1 downto 0 do
  425. begin
  426. cg.a_load_reg_reg(current_asmdata.CurrAsmList,OS_8,OS_8,tcgz80(cg).GetOffsetReg64(left.location.register,left.location.registerhi,i),NR_A);
  427. if (i=(size-1)) and (not unsigned) then
  428. op:=A_SUB
  429. else
  430. op:=A_CP;
  431. current_asmdata.CurrAsmList.Concat(taicpu.op_reg_ref(op,NR_A,tmpref));
  432. if (i=(size-1)) and (not unsigned) then
  433. case actualnodetype of
  434. ltn,
  435. lten:
  436. tcgz80(cg).a_jmp_signed_cmp_3way(current_asmdata.CurrAsmList,truelabel,nil,falselabel);
  437. gtn,
  438. gten:
  439. tcgz80(cg).a_jmp_signed_cmp_3way(current_asmdata.CurrAsmList,falselabel,nil,truelabel);
  440. else
  441. internalerror(2020042202);
  442. end
  443. else if i<>0 then
  444. case actualnodetype of
  445. ltn,
  446. lten:
  447. tcgz80(cg).a_jmp_unsigned_cmp_3way(current_asmdata.CurrAsmList,truelabel,nil,falselabel);
  448. gtn,
  449. gten:
  450. tcgz80(cg).a_jmp_unsigned_cmp_3way(current_asmdata.CurrAsmList,falselabel,nil,truelabel);
  451. else
  452. internalerror(2020042207);
  453. end
  454. else
  455. case actualnodetype of
  456. ltn:
  457. tcgz80(cg).a_jmp_unsigned_cmp_3way(current_asmdata.CurrAsmList,truelabel,falselabel,falselabel);
  458. lten:
  459. tcgz80(cg).a_jmp_unsigned_cmp_3way(current_asmdata.CurrAsmList,truelabel,truelabel,falselabel);
  460. gtn:
  461. tcgz80(cg).a_jmp_unsigned_cmp_3way(current_asmdata.CurrAsmList,falselabel,falselabel,truelabel);
  462. gten:
  463. tcgz80(cg).a_jmp_unsigned_cmp_3way(current_asmdata.CurrAsmList,falselabel,truelabel,truelabel);
  464. else
  465. internalerror(2020042203);
  466. end;
  467. if i<>0 then
  468. tcgz80(cg).adjust_normalized_ref(current_asmdata.CurrAsmList,tmpref,-1);
  469. end;
  470. cg.ungetcpuregister(current_asmdata.CurrAsmList,NR_A);
  471. end
  472. else
  473. hlcg.location_force_reg(current_asmdata.CurrAsmList,right.location,right.resultdef,right.resultdef,false);
  474. end;
  475. case right.location.loc of
  476. LOC_CONSTANT:
  477. begin
  478. cg.getcpuregister(current_asmdata.CurrAsmList,NR_A);
  479. for i:=size-1 downto 0 do
  480. begin
  481. cg.a_load_reg_reg(current_asmdata.CurrAsmList,OS_8,OS_8,tcgz80(cg).GetOffsetReg64(left.location.register,left.location.registerhi,i),NR_A);
  482. if (i=(size-1)) and (not unsigned) then
  483. op:=A_SUB
  484. else
  485. op:=A_CP;
  486. current_asmdata.CurrAsmList.Concat(taicpu.op_reg_const(op,NR_A,byte(right.location.value shr (i*8))));
  487. if (i=(size-1)) and (not unsigned) then
  488. case actualnodetype of
  489. ltn,
  490. lten:
  491. tcgz80(cg).a_jmp_signed_cmp_3way(current_asmdata.CurrAsmList,truelabel,nil,falselabel);
  492. gtn,
  493. gten:
  494. tcgz80(cg).a_jmp_signed_cmp_3way(current_asmdata.CurrAsmList,falselabel,nil,truelabel);
  495. else
  496. internalerror(2020042210);
  497. end
  498. else if i<>0 then
  499. case actualnodetype of
  500. ltn,
  501. lten:
  502. tcgz80(cg).a_jmp_unsigned_cmp_3way(current_asmdata.CurrAsmList,truelabel,nil,falselabel);
  503. gtn,
  504. gten:
  505. tcgz80(cg).a_jmp_unsigned_cmp_3way(current_asmdata.CurrAsmList,falselabel,nil,truelabel);
  506. else
  507. internalerror(2020042211);
  508. end
  509. else
  510. case actualnodetype of
  511. ltn:
  512. tcgz80(cg).a_jmp_unsigned_cmp_3way(current_asmdata.CurrAsmList,truelabel,falselabel,falselabel);
  513. lten:
  514. tcgz80(cg).a_jmp_unsigned_cmp_3way(current_asmdata.CurrAsmList,truelabel,truelabel,falselabel);
  515. gtn:
  516. tcgz80(cg).a_jmp_unsigned_cmp_3way(current_asmdata.CurrAsmList,falselabel,falselabel,truelabel);
  517. gten:
  518. tcgz80(cg).a_jmp_unsigned_cmp_3way(current_asmdata.CurrAsmList,falselabel,truelabel,truelabel);
  519. else
  520. internalerror(2020042215);
  521. end;
  522. end;
  523. cg.ungetcpuregister(current_asmdata.CurrAsmList,NR_A);
  524. end;
  525. LOC_REGISTER,LOC_CREGISTER:
  526. begin
  527. cg.getcpuregister(current_asmdata.CurrAsmList,NR_A);
  528. for i:=size-1 downto 0 do
  529. begin
  530. cg.a_load_reg_reg(current_asmdata.CurrAsmList,OS_8,OS_8,tcgz80(cg).GetOffsetReg64(left.location.register,left.location.registerhi,i),NR_A);
  531. if (i=(size-1)) and (not unsigned) then
  532. op:=A_SUB
  533. else
  534. op:=A_CP;
  535. current_asmdata.CurrAsmList.Concat(taicpu.op_reg_reg(op,NR_A,tcgz80(cg).GetOffsetReg64(right.location.register,right.location.registerhi,i)));
  536. if (i=(size-1)) and (not unsigned) then
  537. case actualnodetype of
  538. ltn,
  539. lten:
  540. tcgz80(cg).a_jmp_signed_cmp_3way(current_asmdata.CurrAsmList,truelabel,nil,falselabel);
  541. gtn,
  542. gten:
  543. tcgz80(cg).a_jmp_signed_cmp_3way(current_asmdata.CurrAsmList,falselabel,nil,truelabel);
  544. else
  545. internalerror(2020042212);
  546. end
  547. else if i<>0 then
  548. case actualnodetype of
  549. ltn,
  550. lten:
  551. tcgz80(cg).a_jmp_unsigned_cmp_3way(current_asmdata.CurrAsmList,truelabel,nil,falselabel);
  552. gtn,
  553. gten:
  554. tcgz80(cg).a_jmp_unsigned_cmp_3way(current_asmdata.CurrAsmList,falselabel,nil,truelabel);
  555. else
  556. internalerror(2020042213);
  557. end
  558. else
  559. case actualnodetype of
  560. ltn:
  561. tcgz80(cg).a_jmp_unsigned_cmp_3way(current_asmdata.CurrAsmList,truelabel,falselabel,falselabel);
  562. lten:
  563. tcgz80(cg).a_jmp_unsigned_cmp_3way(current_asmdata.CurrAsmList,truelabel,truelabel,falselabel);
  564. gtn:
  565. tcgz80(cg).a_jmp_unsigned_cmp_3way(current_asmdata.CurrAsmList,falselabel,falselabel,truelabel);
  566. gten:
  567. tcgz80(cg).a_jmp_unsigned_cmp_3way(current_asmdata.CurrAsmList,falselabel,truelabel,truelabel);
  568. else
  569. internalerror(2020042216);
  570. end;
  571. end;
  572. cg.ungetcpuregister(current_asmdata.CurrAsmList,NR_A);
  573. end;
  574. LOC_REFERENCE,LOC_CREFERENCE:
  575. begin
  576. { Already handled before the case statement. Nothing to do here. }
  577. end;
  578. else
  579. internalerror(2020042106);
  580. end;
  581. end;
  582. end;
  583. function TZ80AddNode.pass_1 : tnode;
  584. begin
  585. result:=inherited pass_1;
  586. {$ifdef dummy}
  587. if not(assigned(result)) then
  588. begin
  589. unsigned:=not(is_signed(left.resultdef)) or
  590. not(is_signed(right.resultdef));
  591. if is_64bit(left.resultdef) and
  592. ((nodetype in [equaln,unequaln]) or
  593. (unsigned and (nodetype in [ltn,lten,gtn,gten]))
  594. ) then
  595. expectloc:=LOC_FLAGS;
  596. end;
  597. { handling boolean expressions }
  598. if not(assigned(result)) and
  599. (
  600. not(is_boolean(left.resultdef)) or
  601. not(is_boolean(right.resultdef)) or
  602. is_dynamic_array(left.resultdef)
  603. ) then
  604. expectloc:=LOC_FLAGS;
  605. {$endif dummy}
  606. end;
  607. procedure TZ80AddNode.second_cmpordinal;
  608. begin
  609. if left.resultdef.size>=2 then
  610. second_cmp16_32_64bit
  611. else
  612. second_cmp;
  613. end;
  614. begin
  615. caddnode:=TZ80AddNode;
  616. end.