ncpuadd.pas 24 KB

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