n8086tcon.pas 6.3 KB

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