nrv32add.pas 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. {
  2. Copyright (c) 2000-2002 by Florian Klaempfl and Jonas Maebe
  3. Code generation for add nodes on the Risc-V32
  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 nrv32add;
  18. {$i fpcdefs.inc}
  19. interface
  20. uses
  21. node, ncgadd, aasmbase, nrvadd, cpubase,
  22. cgbase;
  23. type
  24. trv32addnode = class(trvaddnode)
  25. private
  26. procedure cmp64_le(left_reg, right_reg: TRegister64; unsigned: boolean);
  27. procedure cmp64_lt(left_reg, right_reg: TRegister64; unsigned: boolean);
  28. protected
  29. function use_generic_mul32to64: boolean; override;
  30. procedure second_cmp64bit; override;
  31. end;
  32. implementation
  33. uses
  34. systems,
  35. cutils,verbose,
  36. paramgr,procinfo,
  37. aasmtai,aasmdata,aasmcpu,defutil,
  38. cgcpu,cgutils,nadd,
  39. cpupara,
  40. ncon,nset,
  41. hlcgobj, ncgutil,cgobj;
  42. const
  43. cmpops: array[boolean] of TOpCmp = (OC_LT,OC_B);
  44. procedure trv32addnode.cmp64_lt(left_reg, right_reg: TRegister64;unsigned: boolean);
  45. begin
  46. cg.a_cmp_reg_reg_label(current_asmdata.CurrAsmList,OS_INT,cmpops[unsigned],right_reg.reghi,left_reg.reghi,location.truelabel);
  47. cg.a_cmp_reg_reg_label(current_asmdata.CurrAsmList,OS_INT,OC_NE,left_reg.reghi,right_reg.reghi,location.falselabel);
  48. cg.a_cmp_reg_reg_label(current_asmdata.CurrAsmList,OS_INT,OC_B,right_reg.reglo,left_reg.reglo,location.truelabel);
  49. cg.a_jmp_always(current_asmdata.CurrAsmList,location.falselabel);
  50. end;
  51. procedure trv32addnode.cmp64_le(left_reg, right_reg: TRegister64;unsigned: boolean);
  52. begin
  53. cg.a_cmp_reg_reg_label(current_asmdata.CurrAsmList,OS_INT,cmpops[unsigned],left_reg.reghi,right_reg.reghi,location.falselabel);
  54. cg.a_cmp_reg_reg_label(current_asmdata.CurrAsmList,OS_INT,OC_NE,left_reg.reghi,right_reg.reghi,location.truelabel);
  55. cg.a_cmp_reg_reg_label(current_asmdata.CurrAsmList,OS_INT,OC_B,left_reg.reglo,right_reg.reglo,location.falselabel);
  56. cg.a_jmp_always(current_asmdata.CurrAsmList,location.truelabel);
  57. end;
  58. function trv32addnode.use_generic_mul32to64: boolean;
  59. begin
  60. result:=true;
  61. end;
  62. procedure trv32addnode.second_cmp64bit;
  63. var
  64. truelabel,
  65. falselabel: tasmlabel;
  66. unsigned: boolean;
  67. left_reg,right_reg: TRegister64;
  68. begin
  69. current_asmdata.getjumplabel(truelabel);
  70. current_asmdata.getjumplabel(falselabel);
  71. location_reset_jump(location,truelabel,falselabel);
  72. pass_left_right;
  73. force_reg_left_right(true,true);
  74. unsigned:=not(is_signed(left.resultdef)) or
  75. not(is_signed(right.resultdef));
  76. left_reg:=left.location.register64;
  77. if (right.location.loc=LOC_CONSTANT) then
  78. begin
  79. if lo(right.location.value64)=0 then
  80. right_reg.reglo:=NR_X0
  81. else
  82. begin
  83. right_reg.reglo:=cg.getintregister(current_asmdata.CurrAsmList,OS_INT);
  84. cg.a_load_const_reg(current_asmdata.CurrAsmList,OS_INT,lo(right.location.value64),right_reg.reglo);
  85. end;
  86. if hi(right.location.value64)=0 then
  87. right_reg.reghi:=NR_X0
  88. else
  89. begin
  90. right_reg.reghi:=cg.getintregister(current_asmdata.CurrAsmList,OS_INT);
  91. cg.a_load_const_reg(current_asmdata.CurrAsmList,OS_INT,hi(right.location.value64),right_reg.reghi);
  92. end;
  93. end
  94. else
  95. right_reg:=right.location.register64;
  96. case NodeType of
  97. equaln:
  98. begin
  99. cg.a_cmp_reg_reg_label(current_asmdata.CurrAsmList,OS_INT,OC_NE,left_reg.reghi,right_reg.reghi,location.falselabel);
  100. cg.a_cmp_reg_reg_label(current_asmdata.CurrAsmList,OS_INT,OC_NE,left_reg.reglo,right_reg.reglo,location.falselabel);
  101. cg.a_jmp_always(current_asmdata.CurrAsmList,location.truelabel);
  102. end;
  103. unequaln:
  104. begin
  105. cg.a_cmp_reg_reg_label(current_asmdata.CurrAsmList,OS_INT,OC_NE,left_reg.reghi,right_reg.reghi,location.truelabel);
  106. cg.a_cmp_reg_reg_label(current_asmdata.CurrAsmList,OS_INT,OC_NE,left_reg.reglo,right_reg.reglo,location.truelabel);
  107. cg.a_jmp_always(current_asmdata.CurrAsmList,location.falselabel);
  108. end;
  109. else
  110. if nf_swapped in flags then
  111. case NodeType of
  112. ltn:
  113. cmp64_lt(right_reg, left_reg,unsigned);
  114. lten:
  115. cmp64_le(right_reg, left_reg,unsigned);
  116. gtn:
  117. cmp64_lt(left_reg, right_reg,unsigned);
  118. gten:
  119. cmp64_le(left_reg, right_reg,unsigned);
  120. else
  121. internalerror(2019051034);
  122. end
  123. else
  124. case NodeType of
  125. ltn:
  126. cmp64_lt(left_reg, right_reg,unsigned);
  127. lten:
  128. cmp64_le(left_reg, right_reg,unsigned);
  129. gtn:
  130. cmp64_lt(right_reg, left_reg,unsigned);
  131. gten:
  132. cmp64_le(right_reg, left_reg,unsigned);
  133. else
  134. internalerror(2019051033);
  135. end;
  136. end;
  137. end;
  138. begin
  139. caddnode:=trv32addnode;
  140. end.