ncpuadd.pas 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598
  1. {
  2. Copyright (c) 2000-2009 by Florian Klaempfl and David Zhang
  3. Code generation for add nodes on the FVM32
  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 ncpuadd;
  18. {$i fpcdefs.inc}
  19. interface
  20. uses
  21. node, ncgadd, cpubase, aasmbase, cgbase;
  22. type
  23. tmipsaddnode = class(tcgaddnode)
  24. private
  25. function cmp64_lt(left_reg, right_reg: TRegister64): TRegister;
  26. function cmp64_le(left_reg, right_reg: TRegister64): TRegister;
  27. function cmp64_eq(left_reg, right_reg: TRegister64): TRegister;
  28. function cmp64_ne(left_reg, right_reg: TRegister64): TRegister;
  29. function cmp64_ltu(left_reg, right_reg: TRegister64): TRegister;
  30. function cmp64_leu(left_reg, right_reg: TRegister64): TRegister;
  31. function GetRes_register(unsigned: boolean; this_reg, left_reg, right_reg: TRegister): TRegister;
  32. function GetRes64_register(unsigned: boolean; {this_reg,} left_reg, right_reg: TRegister64): TRegister;
  33. protected
  34. procedure second_addfloat; override;
  35. procedure second_cmpfloat; override;
  36. procedure second_cmpboolean; override;
  37. procedure second_cmpsmallset; override;
  38. procedure second_cmp64bit; override;
  39. procedure second_cmpordinal; override;
  40. end;
  41. implementation
  42. uses
  43. systems,
  44. cutils, verbose,
  45. paramgr,
  46. aasmtai, aasmcpu, aasmdata,
  47. defutil,
  48. {cgbase,} cgcpu, cgutils,
  49. cpupara,
  50. ncon, nset, nadd,
  51. ncgutil, cgobj;
  52. {*****************************************************************************
  53. tmipsaddnode
  54. *****************************************************************************}
  55. function tmipsaddnode.GetRes_register(unsigned: boolean; this_reg, left_reg, right_reg: TRegister): TRegister;
  56. var
  57. tmp_asm_op: tasmop;
  58. begin
  59. case NodeType of
  60. equaln:
  61. tmp_asm_op := A_SEQ;
  62. unequaln:
  63. tmp_asm_op := A_SNE;
  64. else
  65. if not (unsigned) then
  66. begin
  67. if nf_swapped in flags then
  68. case NodeType of
  69. ltn:
  70. tmp_asm_op := A_SGT;
  71. lten:
  72. tmp_asm_op := A_SGE;
  73. gtn:
  74. tmp_asm_op := A_SLT;
  75. gten:
  76. tmp_asm_op := A_SLE;
  77. end
  78. else
  79. case NodeType of
  80. ltn:
  81. tmp_asm_op := A_SLT;
  82. lten:
  83. tmp_asm_op := A_SLE;
  84. gtn:
  85. tmp_asm_op := A_SGT;
  86. gten:
  87. tmp_asm_op := A_SGE;
  88. end;
  89. end
  90. else
  91. begin
  92. if nf_swapped in Flags then
  93. case NodeType of
  94. ltn:
  95. tmp_asm_op := A_SGTU;
  96. lten:
  97. tmp_asm_op := A_SGEU;
  98. gtn:
  99. tmp_asm_op := A_SLTU;
  100. gten:
  101. tmp_asm_op := A_SLEU;
  102. end
  103. else
  104. case NodeType of
  105. ltn:
  106. tmp_asm_op := A_SLTU;
  107. lten:
  108. tmp_asm_op := A_SLEU;
  109. gtn:
  110. tmp_asm_op := A_SGTU;
  111. gten:
  112. tmp_asm_op := A_SGEU;
  113. end;
  114. end;
  115. end;
  116. current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(tmp_asm_op, this_reg, left_reg, right_reg));
  117. GetRes_register := this_reg;
  118. end;
  119. function tmipsaddnode.cmp64_eq(left_reg, right_reg: TRegister64): TRegister;
  120. var
  121. lfcmp64_L4: tasmlabel;
  122. begin
  123. current_asmdata.getjumplabel(lfcmp64_L4);
  124. current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LI, NR_TCR10, 0));
  125. current_asmdata.CurrAsmList.concat(Taicpu.op_reg_reg_sym(A_BNE, left_reg.reghi, right_reg.reghi, lfcmp64_L4));
  126. current_asmdata.CurrAsmList.concat(TAiCpu.Op_none(A_NOP));
  127. current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_sym(A_BNE, left_reg.reglo, right_reg.reglo, lfcmp64_L4));
  128. current_asmdata.CurrAsmList.concat(TAiCpu.Op_none(A_NOP));
  129. current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LI, NR_TCR10, 1));
  130. cg.a_label(current_asmdata.CurrAsmList, lfcmp64_L4);
  131. cmp64_eq := NR_TCR10;
  132. end;
  133. function tmipsaddnode.cmp64_ne(left_reg, right_reg: TRegister64): TRegister;
  134. var
  135. lfcmp64_L4: tasmlabel;
  136. begin
  137. current_asmdata.getjumplabel(lfcmp64_L4);
  138. current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LI, NR_TCR10, 1));
  139. current_asmdata.CurrAsmList.concat(Taicpu.op_reg_reg_sym(A_BNE, left_reg.reghi, right_reg.reghi, lfcmp64_L4));
  140. current_asmdata.CurrAsmList.concat(TAiCpu.Op_none(A_NOP));
  141. current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_sym(A_BNE, left_reg.reglo, right_reg.reglo, lfcmp64_L4));
  142. current_asmdata.CurrAsmList.concat(TAiCpu.Op_none(A_NOP));
  143. current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LI, NR_TCR10, 0));
  144. cg.a_label(current_asmdata.CurrAsmList, lfcmp64_L4);
  145. cmp64_ne := NR_TCR10;
  146. end;
  147. function tmipsaddnode.cmp64_lt(left_reg, right_reg: TRegister64): TRegister;
  148. var
  149. lfcmp64_L4, lfcmp64_L5: tasmlabel;
  150. begin
  151. current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LI, NR_TCR10, 0));
  152. current_asmdata.getjumplabel(lfcmp64_L4);
  153. current_asmdata.getjumplabel(lfcmp64_L5);
  154. current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_SLT, NR_TCR11, left_reg.reghi, right_reg.reghi));
  155. current_asmdata.CurrAsmList.concat(Taicpu.op_reg_reg_sym(A_BNE, NR_TCR11, NR_R0, lfcmp64_L5));
  156. current_asmdata.CurrAsmList.concat(TAiCpu.Op_none(A_NOP));
  157. current_asmdata.CurrAsmList.concat(Taicpu.op_reg_reg_sym(A_BNE, left_reg.reghi, right_reg.reghi, lfcmp64_L4));
  158. current_asmdata.CurrAsmList.concat(TAiCpu.Op_none(A_NOP));
  159. current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_SLTU, NR_TCR11, left_reg.reglo, right_reg.reglo));
  160. current_asmdata.CurrAsmList.concat(Taicpu.op_reg_reg_sym(A_BNE, NR_TCR11, NR_R0, lfcmp64_L5));
  161. current_asmdata.CurrAsmList.concat(TAiCpu.Op_none(A_NOP));
  162. current_asmdata.CurrAsmList.concat(Taicpu.op_sym(A_B, lfcmp64_L4));
  163. current_asmdata.CurrAsmList.concat(TAiCpu.Op_none(A_NOP));
  164. cg.a_label(current_asmdata.CurrAsmList, lfcmp64_L5);
  165. current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LI, NR_TCR10, 1));
  166. cg.a_label(current_asmdata.CurrAsmList, lfcmp64_L4);
  167. cmp64_lt := NR_TCR10;
  168. end;
  169. function tmipsaddnode.cmp64_le(left_reg, right_reg: TRegister64): TRegister;
  170. var
  171. lfcmp64_L4, lfcmp64_L5: tasmlabel;
  172. begin
  173. current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LI, NR_TCR10, 0));
  174. current_asmdata.getjumplabel(lfcmp64_L4);
  175. current_asmdata.getjumplabel(lfcmp64_L5);
  176. current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_SLT, NR_TCR11, right_reg.reghi, left_reg.reghi));
  177. current_asmdata.CurrAsmList.concat(Taicpu.op_reg_reg_sym(A_BNE, NR_TCR11, NR_R0, lfcmp64_L4));
  178. current_asmdata.CurrAsmList.concat(TAiCpu.Op_none(A_NOP));
  179. current_asmdata.CurrAsmList.concat(Taicpu.op_reg_reg_sym(A_BNE, right_reg.reghi, left_reg.reghi, lfcmp64_L5));
  180. current_asmdata.CurrAsmList.concat(TAiCpu.Op_none(A_NOP));
  181. current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_SLTU, NR_TCR11, right_reg.reglo, left_reg.reglo));
  182. current_asmdata.CurrAsmList.concat(Taicpu.op_reg_reg_sym(A_BNE, NR_TCR11, NR_R0, lfcmp64_L4));
  183. current_asmdata.CurrAsmList.concat(TAiCpu.Op_none(A_NOP));
  184. cg.a_label(current_asmdata.CurrAsmList, lfcmp64_L5);
  185. current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LI, NR_TCR10, 1));
  186. cg.a_label(current_asmdata.CurrAsmList, lfcmp64_L4);
  187. cmp64_le := NR_TCR10;
  188. end;
  189. function tmipsaddnode.cmp64_ltu(left_reg, right_reg: TRegister64): TRegister;
  190. var
  191. lfcmp64_L4, lfcmp64_L5: tasmlabel;
  192. begin
  193. current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LI, NR_TCR10, 0));
  194. current_asmdata.getjumplabel(lfcmp64_L4);
  195. current_asmdata.getjumplabel(lfcmp64_L5);
  196. current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_SLTU, NR_TCR11, left_reg.reghi, right_reg.reghi));
  197. current_asmdata.CurrAsmList.concat(Taicpu.op_reg_reg_sym(A_BNE, NR_TCR11, NR_R0, lfcmp64_L5));
  198. current_asmdata.CurrAsmList.concat(TAiCpu.Op_none(A_NOP));
  199. current_asmdata.CurrAsmList.concat(Taicpu.op_reg_reg_sym(A_BNE, left_reg.reghi, right_reg.reghi, lfcmp64_L4));
  200. current_asmdata.CurrAsmList.concat(TAiCpu.Op_none(A_NOP));
  201. current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_SLTU, NR_TCR11, left_reg.reglo, right_reg.reglo));
  202. current_asmdata.CurrAsmList.concat(Taicpu.op_reg_reg_sym(A_BNE, NR_TCR11, NR_R0, lfcmp64_L5));
  203. current_asmdata.CurrAsmList.concat(TAiCpu.Op_none(A_NOP));
  204. current_asmdata.CurrAsmList.concat(Taicpu.op_sym(A_B, lfcmp64_L4));
  205. current_asmdata.CurrAsmList.concat(TAiCpu.Op_none(A_NOP));
  206. cg.a_label(current_asmdata.CurrAsmList, lfcmp64_L5);
  207. current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LI, NR_TCR10, 1));
  208. cg.a_label(current_asmdata.CurrAsmList, lfcmp64_L4);
  209. cmp64_ltu := NR_TCR10;
  210. end;
  211. function tmipsaddnode.cmp64_leu(left_reg, right_reg: TRegister64): TRegister;
  212. var
  213. lfcmp64_L4, lfcmp64_L5: tasmlabel;
  214. begin
  215. current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LI, NR_TCR10, 0));
  216. current_asmdata.getjumplabel(lfcmp64_L4);
  217. current_asmdata.getjumplabel(lfcmp64_L5);
  218. current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_SLTU, NR_TCR11, right_reg.reghi, left_reg.reghi));
  219. current_asmdata.CurrAsmList.concat(Taicpu.op_reg_reg_sym(A_BNE, NR_TCR11, NR_R0, lfcmp64_L4));
  220. current_asmdata.CurrAsmList.concat(TAiCpu.Op_none(A_NOP));
  221. current_asmdata.CurrAsmList.concat(Taicpu.op_reg_reg_sym(A_BNE, right_reg.reghi, left_reg.reghi, lfcmp64_L5));
  222. current_asmdata.CurrAsmList.concat(TAiCpu.Op_none(A_NOP));
  223. current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_SLTU, NR_TCR11, right_reg.reglo, left_reg.reglo));
  224. current_asmdata.CurrAsmList.concat(Taicpu.op_reg_reg_sym(A_BNE, NR_TCR11, NR_R0, lfcmp64_L4));
  225. current_asmdata.CurrAsmList.concat(TAiCpu.Op_none(A_NOP));
  226. cg.a_label(current_asmdata.CurrAsmList, lfcmp64_L5);
  227. current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LI, NR_TCR10, 1));
  228. cg.a_label(current_asmdata.CurrAsmList, lfcmp64_L4);
  229. cmp64_leu := NR_TCR10;
  230. end;
  231. function tmipsaddnode.GetRes64_register(unsigned: boolean; //this_reg: TRegister;
  232. left_reg, right_reg: TRegister64): TRegister;
  233. var
  234. tmpreg: TRegister;
  235. lfcmp64_L4, lfcmp_L5: tasmlabel;
  236. begin
  237. case NodeType of
  238. equaln:
  239. begin
  240. GetRes64_register := cmp64_eq(left_reg, right_reg);
  241. end;
  242. unequaln:
  243. GetRes64_register := cmp64_ne(left_reg, right_reg);
  244. else
  245. if not (unsigned) then
  246. begin
  247. if nf_swapped in flags then
  248. case NodeType of
  249. ltn:
  250. GetRes64_register := cmp64_lt(right_reg, left_reg);
  251. lten:
  252. GetRes64_register := cmp64_le(right_reg, left_reg);
  253. gtn:
  254. GetRes64_register := cmp64_lt(left_reg, right_reg);
  255. gten:
  256. GetRes64_register := cmp64_le(left_reg, right_reg);
  257. end
  258. else
  259. case NodeType of
  260. ltn:
  261. GetRes64_register := cmp64_lt(left_reg, right_reg);
  262. lten:
  263. GetRes64_register := cmp64_le(left_reg, right_reg);
  264. gtn:
  265. GetRes64_register := cmp64_lt(right_reg, left_reg);
  266. gten:
  267. GetRes64_register := cmp64_le(right_reg, left_reg);
  268. end;
  269. end
  270. else
  271. begin
  272. if nf_swapped in Flags then
  273. case NodeType of
  274. ltn:
  275. GetRes64_register := cmp64_ltu(right_reg, left_reg);
  276. lten:
  277. GetRes64_register := cmp64_leu(right_reg, left_reg);
  278. gtn:
  279. GetRes64_register := cmp64_ltu(left_reg, right_reg);
  280. gten:
  281. GetRes64_register := cmp64_leu(left_reg, right_reg);
  282. end
  283. else
  284. case NodeType of
  285. ltn:
  286. GetRes64_register := cmp64_ltu(left_reg, right_reg);
  287. lten:
  288. GetRes64_register := cmp64_leu(left_reg, right_reg);
  289. gtn:
  290. GetRes64_register := cmp64_ltu(right_reg, left_reg);
  291. gten:
  292. GetRes64_register := cmp64_leu(right_reg, left_reg);
  293. end;
  294. end;
  295. end;
  296. end;
  297. procedure tmipsaddnode.second_addfloat;
  298. var
  299. op: TAsmOp;
  300. begin
  301. pass_left_right;
  302. if (nf_swapped in flags) then
  303. swapleftright;
  304. { force fpureg as location, left right doesn't matter
  305. as both will be in a fpureg }
  306. location_force_fpureg(current_asmdata.CurrAsmList, left.location, True);
  307. location_force_fpureg(current_asmdata.CurrAsmList, right.location, (left.location.loc <> LOC_CFPUREGISTER));
  308. location_reset(location, LOC_FPUREGISTER, def_cgsize(resultdef));
  309. if left.location.loc <> LOC_CFPUREGISTER then
  310. location.Register := left.location.Register
  311. else
  312. location.Register := right.location.Register;
  313. case nodetype of
  314. addn:
  315. begin
  316. if location.size = OS_F64 then
  317. op := A_ADD_D
  318. else
  319. op := A_ADD_S;
  320. end;
  321. muln:
  322. begin
  323. if location.size = OS_F64 then
  324. op := A_MUL_D
  325. else
  326. op := A_MUL_S;
  327. end;
  328. subn:
  329. begin
  330. if location.size = OS_F64 then
  331. op := A_SUB_D
  332. else
  333. op := A_SUB_S;
  334. end;
  335. slashn:
  336. begin
  337. if location.size = OS_F64 then
  338. op := A_DIV_D
  339. else
  340. op := A_DIV_S;
  341. end;
  342. else
  343. internalerror(200306014);
  344. end;
  345. current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(op,
  346. location.Register, left.location.Register, right.location.Register));
  347. end;
  348. procedure tmipsaddnode.second_cmpfloat;
  349. var
  350. op: tasmop;
  351. lfcmptrue, lfcmpfalse: tasmlabel;
  352. begin
  353. pass_left_right;
  354. if nf_swapped in flags then
  355. swapleftright;
  356. { force fpureg as location, left right doesn't matter
  357. as both will be in a fpureg }
  358. location_force_fpureg(current_asmdata.CurrAsmList, left.location, True);
  359. location_force_fpureg(current_asmdata.CurrAsmList, right.location, True);
  360. location_reset(location, LOC_REGISTER, OS_INT);
  361. location.Register := NR_TCR0;
  362. case NodeType of
  363. equaln:
  364. begin
  365. if left.location.size = OS_F64 then
  366. op := A_C_EQ_D
  367. else
  368. op := A_C_EQ_S;
  369. current_asmdata.getjumplabel(lfcmpfalse);
  370. current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_OR, location.Register {NR_TCR0}, NR_R0, NR_R0));
  371. current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(op, left.location.Register, right.location.Register));
  372. current_asmdata.CurrAsmList.concat(Taicpu.op_sym(A_BC1F, lfcmpfalse)); //lfcmpfalse
  373. current_asmdata.CurrAsmList.concat(TAiCpu.Op_none(A_NOP));
  374. current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_const(A_ORI, location.Register{NR_TCR0}, NR_R0, 1));
  375. cg.a_label(current_asmdata.CurrAsmList, lfcmpfalse);
  376. end;
  377. unequaln:
  378. begin
  379. if left.location.size = OS_F64 then
  380. op := A_C_EQ_D
  381. else
  382. op := A_C_EQ_S;
  383. current_asmdata.getjumplabel(lfcmpfalse);
  384. current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_const(A_ORI, location.Register{NR_TCR0}, NR_R0, 1));
  385. current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(op, left.location.Register, right.location.Register));
  386. current_asmdata.CurrAsmList.concat(Taicpu.op_sym(A_BC1F, lfcmpfalse));
  387. current_asmdata.CurrAsmList.concat(TAiCpu.Op_none(A_NOP));
  388. current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_OR, location.Register {NR_TCR0}, NR_R0, NR_R0));
  389. cg.a_label(current_asmdata.CurrAsmList, lfcmpfalse);
  390. end;
  391. ltn:
  392. begin
  393. if left.location.size = OS_F64 then
  394. op := A_C_LT_D
  395. else
  396. op := A_C_LT_S;
  397. current_asmdata.getjumplabel(lfcmptrue);
  398. current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_const(A_ORI, location.Register{NR_TCR0}, NR_R0, 1));
  399. current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(op, left.location.Register, right.location.Register));
  400. current_asmdata.CurrAsmList.concat(Taicpu.op_sym(A_BC1T, lfcmptrue));
  401. current_asmdata.CurrAsmList.concat(TAiCpu.Op_none(A_NOP));
  402. current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_OR, location.Register {NR_TCR0}, NR_R0, NR_R0));
  403. cg.a_label(current_asmdata.CurrAsmList, lfcmptrue);
  404. end;
  405. lten:
  406. begin
  407. if left.location.size = OS_F64 then
  408. op := A_C_LE_D
  409. else
  410. op := A_C_LE_S;
  411. current_asmdata.getjumplabel(lfcmptrue);
  412. current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_const(A_ORI, location.Register{NR_TCR0}, NR_R0, 1));
  413. current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(op, left.location.Register, right.location.Register));
  414. current_asmdata.CurrAsmList.concat(Taicpu.op_sym(A_BC1T, lfcmptrue));
  415. current_asmdata.CurrAsmList.concat(TAiCpu.Op_none(A_NOP));
  416. current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_OR, location.Register {NR_TCR0}, NR_R0, NR_R0));
  417. cg.a_label(current_asmdata.CurrAsmList, lfcmptrue);
  418. end;
  419. gtn:
  420. begin
  421. if left.location.size = OS_F64 then
  422. op := A_C_LT_D
  423. else
  424. op := A_C_LT_S;
  425. current_asmdata.getjumplabel(lfcmptrue);
  426. current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_const(A_ORI, location.Register{NR_TCR0}, NR_R0, 1));
  427. current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(op, right.location.Register, left.location.Register));
  428. current_asmdata.CurrAsmList.concat(Taicpu.op_sym(A_BC1T, lfcmptrue));
  429. current_asmdata.CurrAsmList.concat(TAiCpu.Op_none(A_NOP));
  430. current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_OR, location.Register {NR_TCR0}, NR_R0, NR_R0));
  431. cg.a_label(current_asmdata.CurrAsmList, lfcmptrue);
  432. end;
  433. gten:
  434. begin
  435. if left.location.size = OS_F64 then
  436. op := A_C_LE_D
  437. else
  438. op := A_C_LE_S;
  439. current_asmdata.getjumplabel(lfcmptrue);
  440. current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_const(A_ORI, location.Register{NR_TCR0}, NR_R0, 1));
  441. current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(op, right.location.Register, left.location.Register));
  442. current_asmdata.CurrAsmList.concat(Taicpu.op_sym(A_BC1T, lfcmptrue));
  443. current_asmdata.CurrAsmList.concat(TAiCpu.Op_none(A_NOP));
  444. current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_OR, location.Register {NR_TCR0}, NR_R0, NR_R0));
  445. cg.a_label(current_asmdata.CurrAsmList, lfcmptrue);
  446. end;
  447. end; {case}
  448. end;
  449. procedure tmipsaddnode.second_cmpboolean;
  450. var
  451. tmp_right_reg: TRegister;
  452. begin
  453. pass_left_right;
  454. force_reg_left_right(True, True);
  455. tmp_right_reg := NR_NO;
  456. if right.location.loc = LOC_CONSTANT then
  457. begin
  458. tmp_right_reg := cg.GetIntRegister(current_asmdata.CurrAsmList, OS_INT);
  459. current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LI, tmp_right_reg, right.location.Value));
  460. end
  461. else
  462. begin
  463. tmp_right_reg := right.location.Register;
  464. end;
  465. location_reset(location, LOC_REGISTER, OS_INT);
  466. location.Register := GetRes_register(True, NR_TCR0, left.location.Register, tmp_right_reg);
  467. end;
  468. procedure tmipsaddnode.second_cmpsmallset;
  469. var
  470. tmp_right_reg: TRegister;
  471. begin
  472. pass_left_right;
  473. force_reg_left_right(True, True);
  474. tmp_right_reg := NR_NO;
  475. if right.location.loc = LOC_CONSTANT then
  476. begin
  477. tmp_right_reg := cg.GetIntRegister(current_asmdata.CurrAsmList, OS_INT);
  478. current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LI, tmp_right_reg, right.location.Value));
  479. end
  480. else
  481. begin
  482. tmp_right_reg := right.location.Register;
  483. end;
  484. location_reset(location, LOC_REGISTER, OS_INT);
  485. location.Register := GetRes_register(True, NR_TCR0, left.location.Register, tmp_right_reg);
  486. end;
  487. procedure tmipsaddnode.second_cmp64bit;
  488. var
  489. unsigned : boolean;
  490. tmp_left_reg: TRegister;
  491. begin
  492. pass_left_right;
  493. force_reg_left_right(false,false);
  494. unsigned:=not(is_signed(left.resultdef)) or
  495. not(is_signed(right.resultdef));
  496. location_reset(location, LOC_REGISTER, OS_INT);
  497. location.Register := GetRes64_register(unsigned, {NR_TCR0, }left.location.register64, right.location.register64); // NR_TCR0;
  498. end;
  499. procedure tmipsaddnode.second_cmpordinal;
  500. var
  501. unsigned: boolean;
  502. tmp_right_reg: TRegister;
  503. begin
  504. pass_left_right;
  505. force_reg_left_right(True, True);
  506. unsigned := not (is_signed(left.resultdef)) or not (is_signed(right.resultdef));
  507. tmp_right_reg := NR_NO;
  508. if right.location.loc = LOC_CONSTANT then
  509. begin
  510. tmp_right_reg := cg.GetIntRegister(current_asmdata.CurrAsmList, OS_INT);
  511. current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LI, tmp_right_reg, right.location.Value));
  512. end
  513. else
  514. begin
  515. tmp_right_reg := right.location.Register;
  516. end;
  517. location_reset(location, LOC_REGISTER, OS_INT);
  518. location.Register := getres_register(unsigned, NR_TCR0, left.location.Register, tmp_right_reg);
  519. end;
  520. begin
  521. caddnode := tmipsaddnode;
  522. end.