symx86.pas 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. {
  2. Copyright (c) 2014 by Florian Klaempfl
  3. Symbol table overrides for x86
  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 symx86;
  18. {$i fpcdefs.inc}
  19. interface
  20. uses
  21. globtype, cclasses,
  22. symconst, symtype,symdef,symsym;
  23. type
  24. tx86pointerdef = class(tpointerdef)
  25. protected
  26. procedure ppuload_platform(ppufile: tcompilerppufile); override;
  27. procedure ppuwrite_platform(ppufile: tcompilerppufile); override;
  28. public
  29. x86pointertyp : tx86pointertyp;
  30. constructor create(def: tdef); override;
  31. constructor createx86(def:tdef;x86typ:tx86pointertyp);virtual;
  32. function size: asizeint; override;
  33. function getcopy: tstoreddef; override;
  34. function GetTypeName: string; override;
  35. class function default_x86_data_pointer_type: tx86pointertyp; virtual;
  36. end;
  37. tx86pointerdefclass = class of tx86pointerdef;
  38. tx86PtrDefKey = packed record
  39. def: tdef;
  40. x86typ:tx86pointertyp;
  41. end;
  42. { tx86PtrDefHashSet }
  43. tx86PtrDefHashSet = class(TPtrDefHashSet)
  44. private
  45. class procedure Key2FullKey(Key: Pointer; out FullKey: tx86PtrDefKey);
  46. public
  47. function Find(Key: Pointer; KeyLen: Integer): PHashSetItem;override;
  48. function FindOrAdd(Key: Pointer; KeyLen: Integer;
  49. var Found: Boolean): PHashSetItem;override;
  50. function FindOrAdd(Key: Pointer; KeyLen: Integer): PHashSetItem;override;
  51. function Get(Key: Pointer; KeyLen: Integer): TObject;override;
  52. end;
  53. { returns a pointerdef for def, reusing an existing one in case it exists
  54. in the current module }
  55. function getx86pointerdef(def: tdef;x86typ:tx86pointertyp): tpointerdef;
  56. implementation
  57. uses
  58. globals, verbose,
  59. symbase, fmodule;
  60. function getx86pointerdef(def: tdef;x86typ:tx86pointertyp): tpointerdef;
  61. var
  62. res: PHashSetItem;
  63. oldsymtablestack: tsymtablestack;
  64. key: tx86PtrDefKey;
  65. begin
  66. if not assigned(current_module) then
  67. internalerror(2011071101);
  68. key.def:=def;
  69. key.x86typ:=x86typ;
  70. res:=current_module.ptrdefs.FindOrAdd(@key,sizeof(key));
  71. if not assigned(res^.Data) then
  72. begin
  73. { since these pointerdefs can be reused anywhere in the current
  74. unit, add them to the global/staticsymtable }
  75. oldsymtablestack:=symtablestack;
  76. { do not simply push/pop current_module.localsymtable, because
  77. that can have side-effects (e.g., it removes helpers) }
  78. symtablestack:=nil;
  79. res^.Data:=tx86pointerdefclass(cpointerdef).createx86(def,x86typ);
  80. if assigned(current_module.localsymtable) then
  81. current_module.localsymtable.insertdef(tdef(res^.Data))
  82. else
  83. current_module.globalsymtable.insertdef(tdef(res^.Data));
  84. symtablestack:=oldsymtablestack;
  85. end;
  86. result:=tpointerdef(res^.Data);
  87. end;
  88. {****************************************************************************
  89. tx86pointerdef
  90. ****************************************************************************}
  91. procedure tx86pointerdef.ppuload_platform(ppufile: tcompilerppufile);
  92. begin
  93. inherited;
  94. x86pointertyp:=tx86pointertyp(ppufile.getbyte);
  95. end;
  96. procedure tx86pointerdef.ppuwrite_platform(ppufile: tcompilerppufile);
  97. begin
  98. inherited;
  99. ppufile.putbyte(byte(x86pointertyp));
  100. end;
  101. constructor tx86pointerdef.create(def: tdef);
  102. begin
  103. inherited create(def);
  104. x86pointertyp := default_x86_data_pointer_type;
  105. end;
  106. constructor tx86pointerdef.createx86(def: tdef; x86typ: tx86pointertyp);
  107. begin
  108. tabstractpointerdef(self).create(pointerdef,def);
  109. x86pointertyp := x86typ;
  110. has_pointer_math:=cs_pointermath in current_settings.localswitches;
  111. end;
  112. function tx86pointerdef.size: asizeint;
  113. begin
  114. if x86pointertyp in [x86pt_far,x86pt_huge] then
  115. result:=sizeof(pint)+2
  116. else
  117. result:=inherited;
  118. end;
  119. function tx86pointerdef.getcopy: tstoreddef;
  120. begin
  121. result:=inherited;
  122. tx86pointerdef(result).x86pointertyp:=x86pointertyp;
  123. end;
  124. function tx86pointerdef.GetTypeName: string;
  125. begin
  126. result:=inherited;
  127. if x86pointertyp<>default_x86_data_pointer_type then
  128. begin
  129. case x86pointertyp of
  130. x86pt_near:
  131. result:=result+';near';
  132. x86pt_near_cs:
  133. result:=result+';near ''CS''';
  134. x86pt_near_ds:
  135. result:=result+';near ''DS''';
  136. x86pt_near_ss:
  137. result:=result+';near ''SS''';
  138. x86pt_near_es:
  139. result:=result+';near ''ES''';
  140. x86pt_near_fs:
  141. result:=result+';near ''FS''';
  142. x86pt_near_gs:
  143. result:=result+';near ''GS''';
  144. x86pt_far:
  145. result:=result+';far';
  146. x86pt_huge:
  147. result:=result+';huge';
  148. else
  149. internalerror(2013050301);
  150. end;
  151. end;
  152. end;
  153. class function tx86pointerdef.default_x86_data_pointer_type: tx86pointertyp;
  154. begin
  155. result:=x86pt_near;
  156. end;
  157. {****************************************************************************
  158. tx86PtrDefHashSet
  159. ****************************************************************************}
  160. class procedure tx86PtrDefHashSet.Key2FullKey(Key: Pointer; out FullKey: tx86PtrDefKey);
  161. type
  162. pdef=^tdef;
  163. begin
  164. FullKey.def:=pdef(Key)^;
  165. FullKey.x86typ:=tx86pointerdefclass(cpointerdef).default_x86_data_pointer_type;
  166. end;
  167. function tx86PtrDefHashSet.Find(Key: Pointer; KeyLen: Integer): PHashSetItem;
  168. var
  169. FullKey: tx86PtrDefKey;
  170. begin
  171. if KeyLen=SizeOf(tdef) then
  172. begin
  173. Key2FullKey(Key, FullKey);
  174. Result:=inherited Find(@FullKey, SizeOf(FullKey));
  175. end
  176. else
  177. Result:=inherited Find(Key, KeyLen);
  178. end;
  179. function tx86PtrDefHashSet.FindOrAdd(Key: Pointer; KeyLen: Integer; var Found: Boolean): PHashSetItem;
  180. var
  181. FullKey: tx86PtrDefKey;
  182. begin
  183. if KeyLen=SizeOf(tdef) then
  184. begin
  185. Key2FullKey(Key, FullKey);
  186. Result:=inherited FindOrAdd(@FullKey, SizeOf(FullKey), Found);
  187. end
  188. else
  189. Result:=inherited FindOrAdd(Key, KeyLen, Found);
  190. end;
  191. function tx86PtrDefHashSet.FindOrAdd(Key: Pointer; KeyLen: Integer): PHashSetItem;
  192. var
  193. FullKey: tx86PtrDefKey;
  194. begin
  195. if KeyLen=SizeOf(tdef) then
  196. begin
  197. Key2FullKey(Key, FullKey);
  198. Result:=inherited FindOrAdd(@FullKey, SizeOf(FullKey));
  199. end
  200. else
  201. Result:=inherited FindOrAdd(Key, KeyLen);
  202. end;
  203. function tx86PtrDefHashSet.Get(Key: Pointer; KeyLen: Integer): TObject;
  204. var
  205. FullKey: tx86PtrDefKey;
  206. begin
  207. if KeyLen=SizeOf(tdef) then
  208. begin
  209. Key2FullKey(Key, FullKey);
  210. Result:=inherited Get(@FullKey, SizeOf(FullKey));
  211. end
  212. else
  213. Result:=inherited Get(Key, KeyLen);
  214. end;
  215. end.