cg386con.pas 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. {
  2. $Id$
  3. Copyright (c) 1993-98 by Florian Klaempfl
  4. Generate i386 assembler for constants
  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 cg386con;
  19. interface
  20. uses tree;
  21. procedure secondrealconst(var p : ptree);
  22. procedure secondfixconst(var p : ptree);
  23. procedure secondordconst(var p : ptree);
  24. procedure secondniln(var p : ptree);
  25. procedure secondstringconst(var p : ptree);
  26. implementation
  27. uses
  28. cobjects,verbose,
  29. symtable,aasm,i386,
  30. hcodegen;
  31. procedure secondrealconst(var p : ptree);
  32. var
  33. hp1 : pai;
  34. lastlabel : plabel;
  35. found : boolean;
  36. begin
  37. clear_reference(p^.location.reference);
  38. lastlabel:=nil;
  39. found:=false;
  40. { const already used ? }
  41. if p^.labnumber=-1 then
  42. begin
  43. { tries to found an old entry }
  44. hp1:=pai(consts^.first);
  45. while assigned(hp1) do
  46. begin
  47. if hp1^.typ=ait_label then
  48. lastlabel:=pai_label(hp1)^.l
  49. else
  50. begin
  51. if (hp1^.typ=p^.realtyp) and (lastlabel<>nil) then
  52. begin
  53. if ((p^.realtyp=ait_real_64bit) and (pai_double(hp1)^.value=p^.valued)) or
  54. ((p^.realtyp=ait_real_extended) and (pai_extended(hp1)^.value=p^.valued)) or
  55. ((p^.realtyp=ait_real_32bit) and (pai_single(hp1)^.value=p^.valued)) then
  56. begin
  57. { found! }
  58. p^.labnumber:=lastlabel^.nb;
  59. break;
  60. end;
  61. end;
  62. lastlabel:=nil;
  63. end;
  64. hp1:=pai(hp1^.next);
  65. end;
  66. { :-(, we must generate a new entry }
  67. if p^.labnumber=-1 then
  68. begin
  69. getlabel(lastlabel);
  70. p^.labnumber:=lastlabel^.nb;
  71. concat_constlabel(lastlabel,constreal);
  72. case p^.realtyp of
  73. ait_real_64bit : consts^.concat(new(pai_double,init(p^.valued)));
  74. ait_real_32bit : consts^.concat(new(pai_single,init(p^.valued)));
  75. ait_real_extended : consts^.concat(new(pai_extended,init(p^.valued)));
  76. else
  77. internalerror(10120);
  78. end;
  79. end;
  80. end;
  81. stringdispose(p^.location.reference.symbol);
  82. if assigned(lastlabel) then
  83. p^.location.reference.symbol:=stringdup(constlabel2str(lastlabel,constreal))
  84. else
  85. p^.location.reference.symbol:=stringdup(constlabelnb2str(p^.labnumber,constreal));
  86. end;
  87. procedure secondfixconst(var p : ptree);
  88. begin
  89. { an fix comma const. behaves as a memory reference }
  90. p^.location.loc:=LOC_MEM;
  91. p^.location.reference.isintvalue:=true;
  92. p^.location.reference.offset:=p^.valuef;
  93. end;
  94. procedure secondordconst(var p : ptree);
  95. begin
  96. { an integer const. behaves as a memory reference }
  97. p^.location.loc:=LOC_MEM;
  98. p^.location.reference.isintvalue:=true;
  99. p^.location.reference.offset:=p^.value;
  100. end;
  101. procedure secondniln(var p : ptree);
  102. begin
  103. p^.location.loc:=LOC_MEM;
  104. p^.location.reference.isintvalue:=true;
  105. p^.location.reference.offset:=0;
  106. end;
  107. procedure secondstringconst(var p : ptree);
  108. var
  109. hp1 : pai;
  110. lastlabel : plabel;
  111. pc : pchar;
  112. same_string : boolean;
  113. i : word;
  114. begin
  115. clear_reference(p^.location.reference);
  116. lastlabel:=nil;
  117. { const already used ? }
  118. if p^.labstrnumber=-1 then
  119. begin
  120. { tries to found an old entry }
  121. hp1:=pai(consts^.first);
  122. while assigned(hp1) do
  123. begin
  124. if hp1^.typ=ait_label then
  125. lastlabel:=pai_label(hp1)^.l
  126. else
  127. begin
  128. if (hp1^.typ=ait_string) and (lastlabel<>nil) and
  129. (pai_string(hp1)^.len=length(p^.values^)+2) then
  130. begin
  131. same_string:=true;
  132. {$ifndef UseAnsiString}
  133. for i:=1 to length(p^.values^) do
  134. if pai_string(hp1)^.str[i]<>p^.values^[i] then
  135. {$else}
  136. for i:=0 to p^.length do
  137. if pai_string(hp1)^.str[i]<>p^.values[i] then
  138. {$endif}
  139. begin
  140. same_string:=false;
  141. break;
  142. end;
  143. if same_string then
  144. begin
  145. { found! }
  146. p^.labstrnumber:=lastlabel^.nb;
  147. break;
  148. end;
  149. end;
  150. lastlabel:=nil;
  151. end;
  152. hp1:=pai(hp1^.next);
  153. end;
  154. { :-(, we must generate a new entry }
  155. if p^.labstrnumber=-1 then
  156. begin
  157. getlabel(lastlabel);
  158. p^.labstrnumber:=lastlabel^.nb;
  159. {$ifndef UseAnsiString}
  160. getmem(pc,length(p^.values^)+3);
  161. move(p^.values^,pc^,length(p^.values^)+1);
  162. pc[length(p^.values^)+1]:=#0;
  163. {$else UseAnsiString}
  164. pc:=getpcharcopy(p);
  165. {$endif UseAnsiString}
  166. concat_constlabel(lastlabel,conststring);
  167. {$ifdef UseAnsiString}
  168. {$ifdef debug}
  169. consts^.concat(new(pai_asm_comment,init('Header of ansistring')));
  170. {$endif debug}
  171. consts^.concat(new(pai_const,init_32bit(p^.length)));
  172. consts^.concat(new(pai_const,init_32bit(p^.length)));
  173. consts^.concat(new(pai_const,init_32bit(-1)));
  174. { to overcome this problem we set the length explicitly }
  175. { with the ending null char }
  176. consts^.concat(new(pai_string,init_length_pchar(pc,p^.length+1)));
  177. {$else UseAnsiString}
  178. { we still will have a problem if there is a #0 inside the pchar }
  179. consts^.concat(new(pai_string,init_length_pchar(pc,length(p^.values^)+2)));
  180. {$endif UseAnsiString}
  181. end;
  182. end;
  183. stringdispose(p^.location.reference.symbol);
  184. if assigned(lastlabel) then
  185. p^.location.reference.symbol:=stringdup(constlabel2str(lastlabel,conststring))
  186. else
  187. p^.location.reference.symbol:=stringdup(constlabelnb2str(p^.labnumber,conststring));
  188. p^.location.loc := LOC_MEM;
  189. end;
  190. end.
  191. {
  192. $Log$
  193. Revision 1.1 1998-05-23 01:21:02 peter
  194. + aktasmmode, aktoptprocessor, aktoutputformat
  195. + smartlink per module $SMARTLINK-/+ (like MMX) and moved to aktswitches
  196. + $LIBNAME to set the library name where the unit will be put in
  197. * splitted cgi386 a bit (codeseg to large for bp7)
  198. * nasm, tasm works again. nasm moved to ag386nsm.pas
  199. }