nppcset.pas 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  1. {
  2. $Id$
  3. Copyright (c) 1998-2002 by Florian Klaempfl and Carl Eric Codere
  4. Generate PowerPC assembler for in set/case nodes
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program; if not, write to the Free Software
  15. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  16. ****************************************************************************
  17. }
  18. unit nppcset;
  19. {$i fpcdefs.inc}
  20. interface
  21. uses
  22. node,nset,ncgset,cpubase,cgbase,cgobj,aasmbase,aasmtai;
  23. type
  24. tppccasenode = class(tcgcasenode)
  25. protected
  26. procedure genlinearlist(hp : pcaserecord); override;
  27. end;
  28. implementation
  29. uses
  30. globtype,systems,
  31. verbose,globals,
  32. symconst,symdef,defutil,
  33. paramgr,
  34. cpuinfo,
  35. pass_2,cgcpu,
  36. ncon,
  37. tgobj,ncgutil,regvars,rgobj,aasmcpu;
  38. {*****************************************************************************
  39. TCGCASENODE
  40. *****************************************************************************}
  41. procedure tppccasenode.genlinearlist(hp : pcaserecord);
  42. var
  43. first, lastrange : boolean;
  44. last : TConstExprInt;
  45. procedure genitem(t : pcaserecord);
  46. var r:Tregister;
  47. procedure gensub(value:longint);
  48. var
  49. tmpreg: tregister;
  50. begin
  51. value := -value;
  52. if (value >= low(smallint)) and
  53. (value <= high(smallint)) then
  54. exprasmlist.concat(taicpu.op_reg_reg_const(A_ADDIC_,hregister,
  55. hregister,value))
  56. else
  57. begin
  58. tmpreg := cg.getintregister(exprasmlist,OS_INT);
  59. cg.a_load_const_reg(exprasmlist,OS_INT,aword(value),tmpreg);
  60. exprasmlist.concat(taicpu.op_reg_reg_reg(A_ADD_,hregister,
  61. hregister,tmpreg));
  62. cg.ungetregister(exprasmlist,tmpreg);
  63. end;
  64. end;
  65. begin
  66. if assigned(t^.less) then
  67. genitem(t^.less);
  68. { need we to test the first value }
  69. if first and (t^._low>get_min_value(left.resulttype.def)) then
  70. begin
  71. cg.a_cmp_const_reg_label(exprasmlist,OS_INT,jmp_lt,aword(t^._low),hregister,elselabel);
  72. end;
  73. if t^._low=t^._high then
  74. begin
  75. if t^._low-last=0 then
  76. cg.a_cmp_const_reg_label(exprasmlist, opsize, OC_EQ,0,hregister,t^.statement)
  77. else
  78. gensub(longint(t^._low-last));
  79. tcgppc(cg).a_jmp_cond(exprasmlist,OC_EQ,t^.statement);
  80. last:=t^._low;
  81. lastrange := false;
  82. end
  83. else
  84. begin
  85. { it begins with the smallest label, if the value }
  86. { is even smaller then jump immediately to the }
  87. { ELSE-label }
  88. if first then
  89. begin
  90. { have we to ajust the first value ? }
  91. if (t^._low>get_min_value(left.resulttype.def)) then
  92. gensub(longint(t^._low));
  93. end
  94. else
  95. begin
  96. { if there is no unused label between the last and the }
  97. { present label then the lower limit can be checked }
  98. { immediately. else check the range in between: }
  99. gensub(longint(t^._low-last));
  100. if ((t^._low-last) <> 1) or
  101. (not lastrange) then
  102. tcgppc(cg).a_jmp_cond(exprasmlist,jmp_lt,elselabel);
  103. end;
  104. gensub(longint(t^._high-t^._low));
  105. tcgppc(cg).a_jmp_cond(exprasmlist,jmp_le,t^.statement);
  106. last:=t^._high;
  107. lastrange := true;
  108. end;
  109. first:=false;
  110. if assigned(t^.greater) then
  111. genitem(t^.greater);
  112. end;
  113. begin
  114. { do we need to generate cmps? }
  115. if (with_sign and (min_label<0)) or
  116. (opsize = OS_32) then
  117. genlinearcmplist(hp)
  118. else
  119. begin
  120. last:=0;
  121. lastrange:=false;
  122. first:=true;
  123. genitem(hp);
  124. cg.a_jmp_always(exprasmlist,elselabel);
  125. end;
  126. end;
  127. begin
  128. ccasenode:=tppccasenode;
  129. end.
  130. {
  131. $Log$
  132. Revision 1.13 2003-12-09 19:13:32 jonas
  133. * fixed case bugs
  134. Revision 1.12 2003/10/17 01:22:08 florian
  135. * compilation of the powerpc compiler fixed
  136. Revision 1.11 2003/10/01 20:34:49 peter
  137. * procinfo unit contains tprocinfo
  138. * cginfo renamed to cgbase
  139. * moved cgmessage to verbose
  140. * fixed ppc and sparc compiles
  141. Revision 1.10 2003/09/03 19:39:16 peter
  142. * removed empty cga unit
  143. Revision 1.9 2003/09/03 19:35:24 peter
  144. * powerpc compiles again
  145. Revision 1.8 2003/06/14 22:32:43 jonas
  146. * ppc compiles with -dnewra, haven't tried to compile anything with it
  147. yet though
  148. Revision 1.7 2003/02/19 22:00:16 daniel
  149. * Code generator converted to new register notation
  150. - Horribily outdated todo.txt removed
  151. Revision 1.6 2003/01/08 18:43:58 daniel
  152. * Tregister changed into a record
  153. Revision 1.5 2002/11/25 17:43:28 peter
  154. * splitted defbase in defutil,symutil,defcmp
  155. * merged isconvertable and is_equal into compare_defs(_ext)
  156. * made operator search faster by walking the list only once
  157. Revision 1.4 2002/10/21 18:08:05 jonas
  158. * some range errors fixed
  159. Revision 1.3 2002/09/09 13:57:45 jonas
  160. * small optimization to case genlist() case statements
  161. Revision 1.2 2002/09/08 20:14:33 jonas
  162. * use genlinearcmplist() for unsigned 32bit case statements instead
  163. of genlinearlist(), because the addic. instruction always sets the
  164. flags as if the arguments are signed 32bits (for smaller unsigned
  165. types, this doesn't matter since they fit in s32bit)
  166. Revision 1.1 2002/08/11 11:39:12 jonas
  167. + powerpc-specific genlinearlist
  168. Revision 1.13 2002/08/11 06:14:40 florian
  169. * fixed powerpc compilation problems
  170. Revision 1.12 2002/08/10 17:15:12 jonas
  171. * optimizations and bugfix
  172. Revision 1.11 2002/07/28 09:24:18 carl
  173. + generic case node
  174. Revision 1.10 2002/07/23 14:31:00 daniel
  175. * Added internal error when asked to generate code for 'if expr in []'
  176. Revision 1.9 2002/07/23 12:34:30 daniel
  177. * Readded old set code. To use it define 'oldset'. Activated by default
  178. for ppc.
  179. Revision 1.8 2002/07/22 11:48:04 daniel
  180. * Sets are now internally sets.
  181. Revision 1.7 2002/07/21 16:58:20 jonas
  182. * fixed some bugs in tcginnode.pass_2() and optimized the bit test
  183. Revision 1.6 2002/07/20 11:57:54 florian
  184. * types.pas renamed to defbase.pas because D6 contains a types
  185. unit so this would conflicts if D6 programms are compiled
  186. + Willamette/SSE2 instructions to assembler added
  187. Revision 1.5 2002/07/11 14:41:28 florian
  188. * start of the new generic parameter handling
  189. Revision 1.4 2002/07/07 10:16:29 florian
  190. * problems with last commit fixed
  191. Revision 1.3 2002/07/06 20:19:25 carl
  192. + generic set handling
  193. Revision 1.2 2002/07/01 16:23:53 peter
  194. * cg64 patch
  195. * basics for currency
  196. * asnode updates for class and interface (not finished)
  197. Revision 1.1 2002/06/16 08:14:56 carl
  198. + generic sets
  199. }