
-- 1: --------------------------------
-- 2: -- Ivan Levashew aka OCTAGRAM --
-- 3: --         Barnaul, 2009-2010 --
-- 4: --------------------------------

-- 5:

-- 6: with System; use System;

-- 7: with Interfaces; use Interfaces;

-- 8: with System.Storage_Elements; use System.Storage_Elements;

-- 9: with Turbo_Private.Bits; use Turbo_Private.Bits;
with turbo_private;
with system;
with system;
use system;
with interfaces;
use interfaces;
with system.system__storage_elements;
use system.system__storage_elements;
with turbo_private.turbo_private__bits;
use turbo_private.turbo_private__bits;
with system;
with system.system__storage_elements;
with interfaces;
with ada.ada__tags;

-- 10:

-- 11: procedure Turbo_Private.Memory.Move_Fallback
procedure turbo_private.turbo_private__memory.
  turbo_private__memory__move_fallback (source : system__address;
  target : system__address; amount : turbo_private__bits__unsigned_addr) is

-- 12:    (Source, Target : Address; Amount : Unsigned_Addr)

-- 13: is

-- 14:    pragma Preelaborate;
   pragma preelaborate;
   buffer_size : constant  := 4096;

-- 15:    Buffer_Size : constant := 4096;

-- 16:
-- 17: --   type Buffer_Type is new Storage_Array (0 .. Storage_Count (Amount - 1));

-- 18:    type Buffer_Type is new Storage_Array (0 .. Buffer_Size - 1);
   [type turbo_private__memory__move_fallback__Tbuffer_typeB is array (
     -16#8000_0000# .. 16#7FFF_FFFF# range <>) of
     system__storage_elements__storage_element]
   subtype turbo_private__memory__move_fallback__buffer_type is
     turbo_private__memory__move_fallback__Tbuffer_typeB (0 .. 4095);

-- 19:
-- 20: --   Source_Array : Buffer_Type;
-- 21: --   pragma Import (C, Source_Array);
-- 22: --   Target_Array : Buffer_Type;
-- 23: --   pragma Import (C, Target_Array);

-- 24:

-- 25:    Buffer : Buffer_Type;
   freeze turbo_private__memory__move_fallback__Tbuffer_typeB []
   freeze turbo_private__memory__move_fallback__buffer_type []
   buffer : turbo_private__memory__move_fallback__buffer_type;

-- 26:
-- 27:    -- Amount > 0 !

-- 28:    procedure Mini_Move (Source, Target : Address; Amount : Storage_Count) is
   procedure turbo_private__memory__move_fallback__mini_move (source :
     system__address; target : system__address; amount :
     system__storage_elements__storage_count) is
      source_array : turbo_private__memory__move_fallback__buffer_type;

-- 29:       Source_Array : Buffer_Type;

-- 30:       for Source_Array'Address use Source;
      for source_array'address use source;

-- 31:       pragma Import (C, Source_Array);
      pragma import (c, source_array);
      target_array : turbo_private__memory__move_fallback__buffer_type;

-- 32:       Target_Array : Buffer_Type;

-- 33:       for Target_Array'Address use Target;
      for target_array'address use target;

-- 34:       pragma Import (C, Target_Array);
      pragma import (c, target_array);
      freeze source_array []
      [program_error when
        system__storage_elements__integer_address!(source) rem
          source_array'alignment /= 0
        "misaligned address value"]
      freeze target_array []
      [program_error when
        system__storage_elements__integer_address!(target) rem
          target_array'alignment /= 0
        "misaligned address value"]

-- 35:    begin
   begin

-- 36:       Buffer (0 .. Amount - 1) := Source_Array (0 .. Amount - 1);
      [constraint_error when
        not (interfaces__unsigned_32!(amount) <= 16#7FFF_FFFF#)
        "invalid data"]
      [constraint_error when
        amount - 1 >= 0 and then (amount - 1 > 4095)
        "range check failed"]
      [constraint_error when
        not (interfaces__unsigned_32!(amount) <= 16#7FFF_FFFF#)
        "invalid data"]
      [constraint_error when
        amount - 1 >= 0 and then (amount - 1 > 4095)
        "range check failed"]
      [constraint_error when
        [subtype turbo_private__memory__move_fallback__mini_move__T2b is
        [type system__storage_elements__Tstorage_offsetB is new integer]
        [subtype turbo_private__memory__move_fallback__mini_move__T1b is
          system__storage_elements__Tstorage_offsetB range 0 .. amount -
          1]
          turbo_private__memory__move_fallback__Tbuffer_typeB (
          turbo_private__memory__move_fallback__mini_move__T1b)]
        [subtype turbo_private__memory__move_fallback__mini_move__T4b is
        [subtype turbo_private__memory__move_fallback__mini_move__T3b is
          system__storage_elements__Tstorage_offsetB range 0 .. amount -
          1]
          turbo_private__memory__move_fallback__Tbuffer_typeB (
          turbo_private__memory__move_fallback__mini_move__T3b)]
        turbo_private__memory__move_fallback__mini_move__T2b'length /=
          turbo_private__memory__move_fallback__mini_move__T4b'length
        "length check failed"]
      buffer (0 .. amount - 1) := source_array (0 .. amount - 1);

-- 37:       Target_Array (0 .. Amount - 1) := Buffer (0 .. Amount - 1);
      [constraint_error when
        not (interfaces__unsigned_32!(amount) <= 16#7FFF_FFFF#)
        "invalid data"]
      [constraint_error when
        amount - 1 >= 0 and then (amount - 1 > 4095)
        "range check failed"]
      [constraint_error when
        not (interfaces__unsigned_32!(amount) <= 16#7FFF_FFFF#)
        "invalid data"]
      [constraint_error when
        amount - 1 >= 0 and then (amount - 1 > 4095)
        "range check failed"]
      [constraint_error when
        [subtype turbo_private__memory__move_fallback__mini_move__T6b is
        [subtype turbo_private__memory__move_fallback__mini_move__T5b is
          system__storage_elements__Tstorage_offsetB range 0 .. amount -
          1]
          turbo_private__memory__move_fallback__Tbuffer_typeB (
          turbo_private__memory__move_fallback__mini_move__T5b)]
        [subtype turbo_private__memory__move_fallback__mini_move__T8b is
        [subtype turbo_private__memory__move_fallback__mini_move__T7b is
          system__storage_elements__Tstorage_offsetB range 0 .. amount -
          1]
          turbo_private__memory__move_fallback__Tbuffer_typeB (
          turbo_private__memory__move_fallback__mini_move__T7b)]
        turbo_private__memory__move_fallback__mini_move__T6b'length /=
          turbo_private__memory__move_fallback__mini_move__T8b'length
        "length check failed"]
      target_array (0 .. amount - 1) := buffer (0 .. amount - 1);

-- 38:    end Mini_Move;
      return;
   end turbo_private__memory__move_fallback__mini_move;

   amount_div : constant turbo_private__bits__unsigned_addr := amount /

-- 39:

-- 40:    Amount_Div : constant Unsigned_Addr := Amount / Buffer_Size;
     4096;
   amount_mod : constant turbo_private__bits__unsigned_addr := amount rem

-- 41:    Amount_Mod : constant Unsigned_Addr := Amount mod Buffer_Size;
     4096;

-- 42:

-- 43:    procedure Forward_Move is
   procedure turbo_private__memory__move_fallback__forward_move is
      L_1 : label

-- 44:    begin
   begin

-- 45:       if Amount_Div >= 1 then
      if amount_div >= 1 then
         [type turbo_private__bits__Tunsigned_addrB is  mod
           16#1000_0000_0#]
         S9b : turbo_private__bits__Tunsigned_addrB;

-- 46:          for i in 0 .. Amount_Div - 1 loop
         S9b := amount_div - 1;
         L_1 : for i in 0 .. S9b loop

-- 47:             Mini_Move (Source + i * Buffer_Size, Target + i * Buffer_Size, Buffer_Size);
            turbo_private__memory__move_fallback__mini_move (
              turbo_private__bits__Oadd__9 (source, i * 4096),
              turbo_private__bits__Oadd__9 (target, i * 4096), 4096);

-- 48:          end loop;
         end loop L_1;

-- 49:       end if;
      end if;

-- 50:       if Amount_Mod >= 1 then
      if amount_mod >= 1 then

-- 51:          Mini_Move (Source + Amount_Div * Buffer_Size,

-- 52:                     Target + Amount_Div * Buffer_Size,

-- 53:                     Storage_Count (Amount_Mod));
         [constraint_error when
           not (amount_mod <= 16#7FFF_FFFF#)
           "range check failed"]
         turbo_private__memory__move_fallback__mini_move (
           turbo_private__bits__Oadd__9 (source, amount_div * 4096),
           turbo_private__bits__Oadd__9 (target, amount_div * 4096),
           system__storage_elements__storage_count(amount_mod));

-- 54:       end if;
      end if;

-- 55:    end Forward_Move;
      return;
   end turbo_private__memory__move_fallback__forward_move;

-- 56:

-- 57:    procedure Backward_Move is
   procedure turbo_private__memory__move_fallback__backward_move is
      L_2 : label

-- 58:    begin
   begin

-- 59:       if Amount_Mod >= 1 then
      if amount_mod >= 1 then

-- 60:          Mini_Move (Source + Amount_Div * Buffer_Size,

-- 61:                     Target + Amount_Div * Buffer_Size,

-- 62:                     Storage_Count (Amount_Mod));
         [constraint_error when
           not (amount_mod <= 16#7FFF_FFFF#)
           "range check failed"]
         turbo_private__memory__move_fallback__mini_move (
           turbo_private__bits__Oadd__9 (source, amount_div * 4096),
           turbo_private__bits__Oadd__9 (target, amount_div * 4096),
           system__storage_elements__storage_count(amount_mod));

-- 63:       end if;
      end if;

-- 64:       if Amount_Div >= 1 then
      if amount_div >= 1 then
         S11b : turbo_private__bits__Tunsigned_addrB;

-- 65:          for i in reverse 0 .. Amount_Div - 1 loop
         S11b := amount_div - 1;
         L_2 : for i in reverse 0 .. S11b loop

-- 66:             Mini_Move (Source + i * Buffer_Size, Target + i * Buffer_Size, Buffer_Size);
            turbo_private__memory__move_fallback__mini_move (
              turbo_private__bits__Oadd__9 (source, i * 4096),
              turbo_private__bits__Oadd__9 (target, i * 4096), 4096);

-- 67:          end loop;
         end loop L_2;

-- 68:       end if;
      end if;

-- 69:    end Backward_Move;
      return;
   end turbo_private__memory__move_fallback__backward_move;

-- 70:

-- 71: begin
begin

-- 72:    if Amount <= 0 then -- it can't be < 0 because Amount has Unsigned_Addr type
   if amount <= 0 then

-- 73:       return;
      return;

-- 74:    elsif Source = Target then
   elsif source = target then

-- 75:       return;
      return;
   else

-- 76:    elsif Source + Amount <= Target or else
      type turbo_private__memory__move_fallback__A15b is access all
        boolean;
      freeze turbo_private__memory__move_fallback__A15b []
      R16b : turbo_private__memory__move_fallback__A15b :=
        turbo_private__bits__Oadd__9 (source, amount) <= target or else
        turbo_private__bits__Oadd__9 (target, amount) <= source
        'reference;
      [constraint_error when
        not (interfaces__unsigned_32!(R16b.all) >=
          interfaces__unsigned_32!(false) and then
          interfaces__unsigned_32!(R16b.all) <= interfaces__unsigned_32!
          (true))
        "invalid data"]
      if R16b.all then

-- 77:          Target + Amount <= Source then
-- 78:       -- no intersection

-- 79:       Forward_Move;
         turbo_private__memory__move_fallback__forward_move;

-- 80:    elsif Source > Target then
      elsif source > target then

-- 81:       Forward_Move;
         turbo_private__memory__move_fallback__forward_move;

-- 82:    else
      else

-- 83:       Backward_Move;
         turbo_private__memory__move_fallback__backward_move;

-- 84:    end if;
      end if;
   end if;

-- 85: end Turbo_Private.Memory.Move_Fallback;
   return;
end turbo_private.turbo_private__memory.
  turbo_private__memory__move_fallback;
