n8086tcon.pas 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  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,compinnr,
  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. begin
  44. { support word/smallint constants, initialized with Seg() }
  45. if (def.ordtype in [u16bit,s16bit]) and (node.nodetype=inlinen) and
  46. (tinlinenode(node).inlinenumber=in_seg_x) then
  47. begin
  48. hp:=tunarynode(node).left;
  49. if (hp.nodetype=typeconvn) and
  50. (ttypeconvnode(hp).convtype=tc_proc_2_procvar) then
  51. hp:=tunarynode(hp).left;
  52. if hp.nodetype=loadn then
  53. begin
  54. srsym:=tloadnode(hp).symtableentry;
  55. case srsym.typ of
  56. procsym :
  57. begin
  58. pd:=tprocdef(tprocsym(srsym).ProcdefList[0]);
  59. if Tprocsym(srsym).ProcdefList.Count>1 then
  60. Message(parser_e_no_overloaded_procvars);
  61. if po_abstractmethod in pd.procoptions then
  62. Message(type_e_cant_take_address_of_abstract_method)
  63. else
  64. ftcb.emit_tai(Tai_const.Create_seg_name(pd.mangledname),u16inttype);
  65. end;
  66. staticvarsym :
  67. ftcb.emit_tai(Tai_const.Create_seg_name(tstaticvarsym(srsym).mangledname),u16inttype);
  68. labelsym :
  69. ftcb.emit_tai(Tai_const.Create_seg_name(tlabelsym(srsym).mangledname),u16inttype);
  70. else
  71. Message(type_e_variable_id_expected);
  72. end;
  73. end
  74. else
  75. Message(parser_e_illegal_expression);
  76. end
  77. { support word/smallint constants, initialized with Ofs() or Word(@s) }
  78. else if (def.ordtype in [u16bit,s16bit]) and (node.nodetype=typeconvn) and
  79. ((Ttypeconvnode(node).left.nodetype=addrn) or
  80. is_proc2procvar_load(Ttypeconvnode(node).left,pd)) then
  81. begin
  82. hp:=tunarynode(Ttypeconvnode(node).left).left;
  83. if (hp.nodetype=typeconvn) and
  84. (ttypeconvnode(hp).convtype=tc_proc_2_procvar) then
  85. hp:=tunarynode(hp).left;
  86. if hp.nodetype=loadn then
  87. begin
  88. srsym:=tloadnode(hp).symtableentry;
  89. case srsym.typ of
  90. procsym :
  91. begin
  92. pd:=tprocdef(tprocsym(srsym).ProcdefList[0]);
  93. if Tprocsym(srsym).ProcdefList.Count>1 then
  94. Message(parser_e_no_overloaded_procvars);
  95. if po_abstractmethod in pd.procoptions then
  96. Message(type_e_cant_take_address_of_abstract_method)
  97. else
  98. ftcb.emit_tai(Tai_const.Createname_near(pd.mangledname,0),u16inttype);
  99. end;
  100. staticvarsym :
  101. ftcb.emit_tai(Tai_const.Createname_near(tstaticvarsym(srsym).mangledname,0),u16inttype);
  102. labelsym :
  103. ftcb.emit_tai(Tai_const.Createname_near(tlabelsym(srsym).mangledname,0),u16inttype);
  104. else
  105. Message(type_e_variable_id_expected);
  106. end;
  107. end
  108. else
  109. Message(parser_e_illegal_expression);
  110. end
  111. else
  112. inherited;
  113. end;
  114. procedure ti8086typedconstbuilder.tc_emit_pointerdef(def: tpointerdef; var node: tnode);
  115. var
  116. hp: tnode;
  117. begin
  118. { remove equal typecasts for pointer/nil addresses }
  119. if (node.nodetype=typeconvn) then
  120. with Ttypeconvnode(node) do
  121. if (left.nodetype in [addrn,niln]) and equal_defs(def,node.resultdef) then
  122. begin
  123. hp:=left;
  124. left:=nil;
  125. node.free;
  126. node:=hp;
  127. end;
  128. { const pointer ? }
  129. if (node.nodetype = pointerconstn) then
  130. begin
  131. ftcb.queue_init(def);
  132. if is_farpointer(def) or is_hugepointer(def) then
  133. begin
  134. ftcb.queue_typeconvn(s32inttype,def);
  135. ftcb.queue_emit_ordconst(longint(tpointerconstnode(node).value),s32inttype);
  136. end
  137. else
  138. begin
  139. ftcb.queue_typeconvn(s16inttype,def);
  140. ftcb.queue_emit_ordconst(smallint(tpointerconstnode(node).value),s16inttype);
  141. end;
  142. end
  143. else if node.nodetype=niln then
  144. begin
  145. if is_farpointer(def) or is_hugepointer(def) then
  146. ftcb.emit_tai(Tai_const.Create_32bit(0),u32inttype)
  147. else
  148. ftcb.emit_tai(Tai_const.Create_16bit(0),u16inttype);
  149. end
  150. else
  151. inherited tc_emit_pointerdef(def, node);
  152. end;
  153. begin
  154. ctypedconstbuilder:=ti8086typedconstbuilder;
  155. end.