{
    Copyright (c) 2016 by Florian Klaempfl

    Code generation for memory related nodes on the AVR

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

 ****************************************************************************
}
unit navrmem;

{$i fpcdefs.inc}

  interface

    uses
      nmem,ncgmem;

    type
      tavraddrnode = class(tcgaddrnode)
        procedure pass_generate_code;override;
      end;

  implementation

    uses
      verbose,
      cpubase,
      aasmdata,
      cgbase,cgutils,
      hlcgobj,
      node,
      pass_2;

    procedure tavraddrnode.pass_generate_code;
      var
        href : treference;
      begin
         secondpass(left);

         href:=left.location.reference;

         if ((href.addressmode=AM_UNCHANGED) and (href.offset=0) and not(assigned(href.symbol))) and
           ((href.base<>NR_NO) xor (href.index<>NR_NO)) then
           begin
             location_reset(location,LOC_CREGISTER,int_cgsize(resultdef.size));
             if href.base<>NR_NO then
               location.register:=href.base
             else if href.index<>NR_NO then
               location.register:=href.index
             else
               internalerror(2016112003);
           end
         else
           begin
             location_reset(location,LOC_REGISTER,int_cgsize(resultdef.size));
             location.register:=hlcg.getaddressregister(current_asmdata.CurrAsmList,resultdef);
             if not(left.location.loc in [LOC_REFERENCE,LOC_CREFERENCE]) then
               { on x86_64-win64, array of chars can be returned in registers, however,
                 when passing these arrays to other functions, the compiler wants to take
                 the address of the array so when the addrnode has been created internally,
                 we have to force the data into memory, see also tw14388.pp
               }
               if nf_internal in flags then
                 hlcg.location_force_mem(current_asmdata.CurrAsmList,left.location,left.resultdef)
               else
                 internalerror(2017072801);
             hlcg.a_loadaddr_ref_reg(current_asmdata.CurrAsmList,left.resultdef,resultdef,left.location.reference,location.register);
           end;
      end;

begin
  caddrnode:=tavraddrnode;
end.

