n8086util.pas 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  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. symdef;
  35. class procedure ti8086nodeutils.InsertMemorySizes;
  36. begin
  37. inherited;
  38. if current_settings.x86memorymodel<>mm_tiny then
  39. InsertStackSegment;
  40. InsertHeapSegment;
  41. if current_settings.x86memorymodel in x86_near_data_models then
  42. InsertStackPlusHeapSize;
  43. end;
  44. class procedure ti8086nodeutils.InsertStackSegment;
  45. var
  46. stacksizeleft,stackblock: LongInt;
  47. i: Integer;
  48. begin
  49. maybe_new_object_file(current_asmdata.asmlists[al_globals]);
  50. new_section(current_asmdata.asmlists[al_globals],sec_stack,'__stack', 16);
  51. current_asmdata.asmlists[al_globals].concat(tai_symbol.Createname_global('___stack', AT_DATA, stacksize, carraydef.getreusable(u8inttype,stacksize)));
  52. { HACK: since tai_datablock's size parameter is aint, which cannot be
  53. larger than 32767 on i8086, but we'd like to support stack size of
  54. up to 64kb, we may need to use several tai_datablocks to reserve
  55. the stack segment }
  56. i:=0;
  57. stacksizeleft:=stacksize;
  58. while stacksizeleft>0 do
  59. begin
  60. stackblock:=min(stacksizeleft,high(aint));
  61. current_asmdata.asmlists[al_globals].concat(tai_datablock.Create('___stackblock'+IntToStr(i),stackblock,carraydef.getreusable(u8inttype,stackblock)));
  62. dec(stacksizeleft,stackblock);
  63. inc(i);
  64. end;
  65. current_asmdata.asmlists[al_globals].concat(tai_symbol.Createname_global('___stacktop',AT_DATA,0,voidtype));
  66. end;
  67. class procedure ti8086nodeutils.InsertHeapSegment;
  68. var
  69. heapsizeleft,heapblock: LongInt;
  70. i: Integer;
  71. begin
  72. maybe_new_object_file(current_asmdata.asmlists[al_globals]);
  73. new_section(current_asmdata.asmlists[al_globals],sec_heap,'__heap', 16);
  74. current_asmdata.asmlists[al_globals].concat(tai_symbol.Createname_global('___heap', AT_DATA, heapsize,carraydef.getreusable(u8inttype,heapsize)));
  75. { HACK: since tai_datablock's size parameter is aint, which cannot be
  76. larger than 32767 on i8086, but we'd like to support heap size of
  77. up to 640kb, we may need to use several tai_datablocks to reserve
  78. the heap segment }
  79. i:=0;
  80. heapsizeleft:=heapsize;
  81. while heapsizeleft>0 do
  82. begin
  83. heapblock:=min(heapsizeleft,high(aint));
  84. current_asmdata.asmlists[al_globals].concat(tai_datablock.Create('___heapblock'+IntToStr(i),heapblock,carraydef.getreusable(u8inttype,heapblock)));
  85. dec(heapsizeleft,heapblock);
  86. inc(i);
  87. end;
  88. current_asmdata.asmlists[al_globals].concat(tai_symbol.Createname_global('___heaptop',AT_DATA,0,voidtype));
  89. end;
  90. class procedure ti8086nodeutils.InsertStackPlusHeapSize;
  91. var
  92. maxheapsize_para: Word;
  93. stacksize_para: Word;
  94. begin
  95. maxheapsize_para:=(maxheapsize+15) div 16;
  96. stacksize_para:=(stacksize+15) div 16;
  97. maybe_new_object_file(current_asmdata.asmlists[al_globals]);
  98. new_section(current_asmdata.asmlists[al_globals],sec_data,'__fpc_stackplusmaxheap_in_para',sizeof(pint));
  99. current_asmdata.asmlists[al_globals].concat(Tai_symbol.Createname_global('__fpc_stackplusmaxheap_in_para',AT_DATA,4,u32inttype));
  100. current_asmdata.asmlists[al_globals].concat(Tai_const.Create_16bit(min($1000,stacksize_para+maxheapsize_para)));
  101. end;
  102. begin
  103. cnodeutils:=ti8086nodeutils;
  104. end.