nmos6502add.pas 27 KB

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