n8086tcon.pas 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. {
  2. Copyright (c) 1998-2011 by Florian Klaempfl, Jonas Maebe
  3. Generates i8086 assembler for typed constant declarations
  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 n8086tcon;
  18. {$i fpcdefs.inc}
  19. interface
  20. uses
  21. node,symdef,ngtcon;
  22. type
  23. { ti8086typedconstbuilder }
  24. ti8086typedconstbuilder = class(tasmlisttypedconstbuilder)
  25. protected
  26. procedure tc_emit_orddef(def: torddef; var node: tnode);override;
  27. procedure tc_emit_pointerdef(def: tpointerdef; var node: tnode);override;
  28. end;
  29. implementation
  30. uses
  31. verbose,
  32. ncon,ncnv,ninl,nld,
  33. defcmp,defutil,
  34. aasmtai,
  35. symconst,symtype,symsym,symcpu,
  36. htypechk;
  37. { ti8086typedconstbuilder }
  38. procedure ti8086typedconstbuilder.tc_emit_orddef(def: torddef; var node: tnode);
  39. var
  40. hp: tnode;
  41. srsym: tsym;
  42. pd: tprocdef;
  43. resourcestrrec: trecorddef;
  44. begin
  45. { support word/smallint constants, initialized with Seg() }
  46. if (def.ordtype in [u16bit,s16bit]) and (node.nodetype=inlinen) and
  47. (tinlinenode(node).inlinenumber=in_seg_x) then
  48. begin
  49. hp:=tunarynode(node).left;
  50. if hp.nodetype=loadn then
  51. begin
  52. srsym:=tloadnode(hp).symtableentry;
  53. case srsym.typ of
  54. procsym :
  55. begin
  56. pd:=tprocdef(tprocsym(srsym).ProcdefList[0]);
  57. if Tprocsym(srsym).ProcdefList.Count>1 then
  58. Message(parser_e_no_overloaded_procvars);
  59. if po_abstractmethod in pd.procoptions then
  60. Message(type_e_cant_take_address_of_abstract_method)
  61. else
  62. ftcb.emit_tai(Tai_const.Create_seg_name(pd.mangledname),u16inttype);
  63. end;
  64. staticvarsym :
  65. ftcb.emit_tai(Tai_const.Create_seg_name(tstaticvarsym(srsym).mangledname),u16inttype);
  66. labelsym :
  67. ftcb.emit_tai(Tai_const.Create_seg_name(tlabelsym(srsym).mangledname),u16inttype);
  68. else
  69. Message(type_e_variable_id_expected);
  70. end;
  71. end
  72. else
  73. Message(parser_e_illegal_expression);
  74. end
  75. { support word/smallint constants, initialized with Ofs() or Word(@s) }
  76. else if (def.ordtype in [u16bit,s16bit]) and (node.nodetype=typeconvn) and
  77. ((Ttypeconvnode(node).left.nodetype=addrn) or
  78. is_proc2procvar_load(Ttypeconvnode(node).left,pd)) then
  79. begin
  80. hp:=tunarynode(Ttypeconvnode(node).left).left;
  81. if hp.nodetype=loadn then
  82. begin
  83. srsym:=tloadnode(hp).symtableentry;
  84. case srsym.typ of
  85. procsym :
  86. begin
  87. pd:=tprocdef(tprocsym(srsym).ProcdefList[0]);
  88. if Tprocsym(srsym).ProcdefList.Count>1 then
  89. Message(parser_e_no_overloaded_procvars);
  90. if po_abstractmethod in pd.procoptions then
  91. Message(type_e_cant_take_address_of_abstract_method)
  92. else
  93. ftcb.emit_tai(Tai_const.Createname(pd.mangledname,0),u16inttype);
  94. end;
  95. staticvarsym :
  96. ftcb.emit_tai(Tai_const.Createname(tstaticvarsym(srsym).mangledname,0),u16inttype);
  97. labelsym :
  98. ftcb.emit_tai(Tai_const.Createname(tlabelsym(srsym).mangledname,0),u16inttype);
  99. else
  100. Message(type_e_variable_id_expected);
  101. end;
  102. end
  103. else
  104. Message(parser_e_illegal_expression);
  105. end
  106. else
  107. inherited;
  108. end;
  109. procedure ti8086typedconstbuilder.tc_emit_pointerdef(def: tpointerdef; var node: tnode);
  110. var
  111. hp: tnode;
  112. begin
  113. { remove equal typecasts for pointer/nil addresses }
  114. if (node.nodetype=typeconvn) then
  115. with Ttypeconvnode(node) do
  116. if (left.nodetype in [addrn,niln]) and equal_defs(def,node.resultdef) then
  117. begin
  118. hp:=left;
  119. left:=nil;
  120. node.free;
  121. node:=hp;
  122. end;
  123. { const pointer ? }
  124. if (node.nodetype = pointerconstn) then
  125. begin
  126. ftcb.queue_init(def);
  127. if is_farpointer(def) or is_hugepointer(def) then
  128. begin
  129. ftcb.queue_typeconvn(s32inttype,def);
  130. ftcb.queue_emit_ordconst(longint(tpointerconstnode(node).value),s32inttype);
  131. end
  132. else
  133. begin
  134. ftcb.queue_typeconvn(s16inttype,def);
  135. ftcb.queue_emit_ordconst(smallint(tpointerconstnode(node).value),s16inttype);
  136. end;
  137. end
  138. else if node.nodetype=niln then
  139. begin
  140. if is_farpointer(def) or is_hugepointer(def) then
  141. ftcb.emit_tai(Tai_const.Create_32bit(0),u32inttype)
  142. else
  143. ftcb.emit_tai(Tai_const.Create_16bit(0),u16inttype);
  144. end
  145. else
  146. inherited tc_emit_pointerdef(def, node);
  147. end;
  148. begin
  149. ctypedconstbuilder:=ti8086typedconstbuilder;
  150. end.