nppcset.pas 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  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,cginfo,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,defbase,
  33. paramgr,
  34. pass_2,cgcpu,
  35. ncon,
  36. cga,tgobj,ncgutil,regvars,rgobj,aasmcpu;
  37. {*****************************************************************************
  38. TCGCASENODE
  39. *****************************************************************************}
  40. procedure tppccasenode.genlinearlist(hp : pcaserecord);
  41. var
  42. first : boolean;
  43. last : TConstExprInt;
  44. resflags: tresflags;
  45. procedure genitem(t : pcaserecord);
  46. procedure gensub(value:longint);
  47. var
  48. tmpreg: tregister;
  49. begin
  50. value := -value;
  51. if (value >= low(smallint)) and
  52. (value <= high(smallint)) then
  53. exprasmlist.concat(taicpu.op_reg_reg_const(A_ADDIC_,hregister,
  54. hregister,value))
  55. else
  56. begin
  57. tmpreg := cg.get_scratch_reg_int(exprasmlist);
  58. cg.a_load_const_reg(exprasmlist,OS_INT,value,tmpreg);
  59. exprasmlist.concat(taicpu.op_reg_reg_reg(A_ADD_,hregister,
  60. hregister,tmpreg));
  61. cg.free_scratch_reg(exprasmlist,tmpreg);
  62. end;
  63. end;
  64. begin
  65. if assigned(t^.less) then
  66. genitem(t^.less);
  67. { need we to test the first value }
  68. if first and (t^._low>get_min_value(left.resulttype.def)) then
  69. begin
  70. cg.a_cmp_const_reg_label(exprasmlist,OS_INT,jmp_lt,
  71. longint(t^._low),hregister,elselabel);
  72. end;
  73. if t^._low=t^._high then
  74. begin
  75. if t^._low-last=0 then
  76. exprasmlist.concat(taicpu.op_reg_reg_const(A_CMPWI,R_CR0,
  77. hregister,0))
  78. else
  79. gensub(longint(t^._low-last));
  80. last:=t^._low;
  81. resflags.cr := R_CR0;
  82. resflags.flag := F_EQ;
  83. cg.a_jmp_flags(exprasmlist,resflags,t^.statement);
  84. end
  85. else
  86. begin
  87. { it begins with the smallest label, if the value }
  88. { is even smaller then jump immediately to the }
  89. { ELSE-label }
  90. if first then
  91. begin
  92. { have we to ajust the first value ? }
  93. if (t^._low>get_min_value(left.resulttype.def)) then
  94. gensub(longint(t^._low));
  95. end
  96. else
  97. begin
  98. { if there is no unused label between the last and the }
  99. { present label then the lower limit can be checked }
  100. { immediately. else check the range in between: }
  101. { note: you can't use gensub() here because dec doesn't }
  102. { change the carry flag (needed for jmp_lxx) (JM) }
  103. gensub(longint(t^._low-last));
  104. tcgppc(cg).a_jmp_cond(exprasmlist,jmp_lt,elselabel);
  105. end;
  106. gensub(longint(t^._high-t^._low));
  107. tcgppc(cg).a_jmp_cond(exprasmlist,jmp_le,t^.statement);
  108. last:=t^._high;
  109. end;
  110. first:=false;
  111. if assigned(t^.greater) then
  112. genitem(t^.greater);
  113. end;
  114. begin
  115. { do we need to generate cmps? }
  116. if (with_sign and (min_label<0)) then
  117. genlinearcmplist(hp)
  118. else
  119. begin
  120. last:=0;
  121. first:=true;
  122. genitem(hp);
  123. cg.a_jmp_always(exprasmlist,elselabel);
  124. end;
  125. end;
  126. begin
  127. ccasenode:=tppccasenode;
  128. end.
  129. {
  130. $Log$
  131. Revision 1.1 2002-08-11 11:39:12 jonas
  132. + powerpc-specific genlinearlist
  133. Revision 1.13 2002/08/11 06:14:40 florian
  134. * fixed powerpc compilation problems
  135. Revision 1.12 2002/08/10 17:15:12 jonas
  136. * optimizations and bugfix
  137. Revision 1.11 2002/07/28 09:24:18 carl
  138. + generic case node
  139. Revision 1.10 2002/07/23 14:31:00 daniel
  140. * Added internal error when asked to generate code for 'if expr in []'
  141. Revision 1.9 2002/07/23 12:34:30 daniel
  142. * Readded old set code. To use it define 'oldset'. Activated by default
  143. for ppc.
  144. Revision 1.8 2002/07/22 11:48:04 daniel
  145. * Sets are now internally sets.
  146. Revision 1.7 2002/07/21 16:58:20 jonas
  147. * fixed some bugs in tcginnode.pass_2() and optimized the bit test
  148. Revision 1.6 2002/07/20 11:57:54 florian
  149. * types.pas renamed to defbase.pas because D6 contains a types
  150. unit so this would conflicts if D6 programms are compiled
  151. + Willamette/SSE2 instructions to assembler added
  152. Revision 1.5 2002/07/11 14:41:28 florian
  153. * start of the new generic parameter handling
  154. Revision 1.4 2002/07/07 10:16:29 florian
  155. * problems with last commit fixed
  156. Revision 1.3 2002/07/06 20:19:25 carl
  157. + generic set handling
  158. Revision 1.2 2002/07/01 16:23:53 peter
  159. * cg64 patch
  160. * basics for currency
  161. * asnode updates for class and interface (not finished)
  162. Revision 1.1 2002/06/16 08:14:56 carl
  163. + generic sets
  164. }