n8086util.pas 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. {
  2. Copyright (c) 2014 by Nikolay Nikolov
  3. i8086 version of some node tree helper routines
  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 n8086util;
  18. {$i fpcdefs.inc}
  19. interface
  20. uses
  21. ngenutil;
  22. type
  23. ti8086nodeutils = class(tnodeutils)
  24. class procedure InsertMemorySizes; override;
  25. class procedure InsertStackSegment;
  26. class procedure InsertHeapSegment;
  27. class procedure InsertStackPlusHeapSize;
  28. end;
  29. implementation
  30. uses
  31. sysutils,cutils,
  32. globtype,globals,cpuinfo,
  33. aasmbase,aasmdata,aasmtai;
  34. class procedure ti8086nodeutils.InsertMemorySizes;
  35. begin
  36. inherited;
  37. if current_settings.x86memorymodel<>mm_tiny then
  38. InsertStackSegment;
  39. InsertHeapSegment;
  40. if current_settings.x86memorymodel in x86_near_data_models then
  41. InsertStackPlusHeapSize;
  42. end;
  43. class procedure ti8086nodeutils.InsertStackSegment;
  44. var
  45. stacksizeleft,stackblock: LongInt;
  46. i: Integer;
  47. begin
  48. maybe_new_object_file(current_asmdata.asmlists[al_globals]);
  49. new_section(current_asmdata.asmlists[al_globals],sec_stack,'__stack', 16);
  50. current_asmdata.asmlists[al_globals].concat(tai_symbol.Createname_global('___stack', AT_DATA, stacksize));
  51. { HACK: since tai_datablock's size parameter is aint, which cannot be
  52. larger than 32767 on i8086, but we'd like to support stack size of
  53. up to 64kb, we may need to use several tai_datablocks to reserve
  54. the stack segment }
  55. i:=0;
  56. stacksizeleft:=stacksize;
  57. while stacksizeleft>0 do
  58. begin
  59. stackblock:=min(stacksizeleft,high(aint));
  60. current_asmdata.asmlists[al_globals].concat(tai_datablock.Create('___stackblock'+IntToStr(i),stackblock));
  61. dec(stacksizeleft,stackblock);
  62. inc(i);
  63. end;
  64. current_asmdata.asmlists[al_globals].concat(tai_symbol.Createname_global('___stacktop',AT_DATA,0));
  65. end;
  66. class procedure ti8086nodeutils.InsertHeapSegment;
  67. var
  68. heapsizeleft,heapblock: LongInt;
  69. i: Integer;
  70. begin
  71. maybe_new_object_file(current_asmdata.asmlists[al_globals]);
  72. new_section(current_asmdata.asmlists[al_globals],sec_heap,'__heap', 16);
  73. current_asmdata.asmlists[al_globals].concat(tai_symbol.Createname_global('___heap', AT_DATA, heapsize));
  74. { HACK: since tai_datablock's size parameter is aint, which cannot be
  75. larger than 32767 on i8086, but we'd like to support heap size of
  76. up to 640kb, we may need to use several tai_datablocks to reserve
  77. the heap segment }
  78. i:=0;
  79. heapsizeleft:=heapsize;
  80. while heapsizeleft>0 do
  81. begin
  82. heapblock:=min(heapsizeleft,high(aint));
  83. current_asmdata.asmlists[al_globals].concat(tai_datablock.Create('___heapblock'+IntToStr(i),heapblock));
  84. dec(heapsizeleft,heapblock);
  85. inc(i);
  86. end;
  87. current_asmdata.asmlists[al_globals].concat(tai_symbol.Createname_global('___heaptop',AT_DATA,0));
  88. end;
  89. class procedure ti8086nodeutils.InsertStackPlusHeapSize;
  90. var
  91. maxheapsize_para: Word;
  92. stacksize_para: Word;
  93. begin
  94. maxheapsize_para:=(maxheapsize+15) div 16;
  95. stacksize_para:=(stacksize+15) div 16;
  96. maybe_new_object_file(current_asmdata.asmlists[al_globals]);
  97. new_section(current_asmdata.asmlists[al_globals],sec_data,'__fpc_stackplusmaxheap_in_para',sizeof(pint));
  98. current_asmdata.asmlists[al_globals].concat(Tai_symbol.Createname_global('__fpc_stackplusmaxheap_in_para',AT_DATA,4));
  99. current_asmdata.asmlists[al_globals].concat(Tai_const.Create_16bit(min($1000,stacksize_para+maxheapsize_para)));
  100. end;
  101. begin
  102. cnodeutils:=ti8086nodeutils;
  103. end.