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