navrmem.pas 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. {
  2. Copyright (c) 2016 by Florian Klaempfl
  3. Code generation for memory related nodes on the AVR
  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 navrmem;
  18. {$i fpcdefs.inc}
  19. interface
  20. uses
  21. nmem,ncgmem;
  22. type
  23. tavraddrnode = class(tcgaddrnode)
  24. procedure pass_generate_code;override;
  25. end;
  26. implementation
  27. uses
  28. verbose,
  29. cpubase,
  30. aasmdata,
  31. cgbase,cgutils,
  32. hlcgobj,
  33. node,
  34. pass_2;
  35. procedure tavraddrnode.pass_generate_code;
  36. var
  37. href : treference;
  38. begin
  39. secondpass(left);
  40. href:=left.location.reference;
  41. if ((href.addressmode=AM_UNCHANGED) and (href.offset=0) and not(assigned(href.symbol))) and
  42. ((href.base<>NR_NO) xor (href.index<>NR_NO)) then
  43. begin
  44. location_reset(location,LOC_CREGISTER,int_cgsize(resultdef.size));
  45. if href.base<>NR_NO then
  46. location.register:=href.base
  47. else if href.index<>NR_NO then
  48. location.register:=href.index
  49. else
  50. internalerror(2016112003);
  51. end
  52. else
  53. begin
  54. location_reset(location,LOC_REGISTER,int_cgsize(resultdef.size));
  55. location.register:=hlcg.getaddressregister(current_asmdata.CurrAsmList,resultdef);
  56. if not(left.location.loc in [LOC_REFERENCE,LOC_CREFERENCE]) then
  57. { on x86_64-win64, array of chars can be returned in registers, however,
  58. when passing these arrays to other functions, the compiler wants to take
  59. the address of the array so when the addrnode has been created internally,
  60. we have to force the data into memory, see also tw14388.pp
  61. }
  62. if nf_internal in flags then
  63. hlcg.location_force_mem(current_asmdata.CurrAsmList,left.location,left.resultdef)
  64. else
  65. internalerror(2017072801);
  66. hlcg.a_loadaddr_ref_reg(current_asmdata.CurrAsmList,left.resultdef,resultdef,left.location.reference,location.register);
  67. end;
  68. end;
  69. begin
  70. caddrnode:=tavraddrnode;
  71. end.