Patch title: Release 94 bulk changes
Abstract:
File: /pliant/language/basic/swap.pli
Key:
    Removed line
    Added line
# Copyright  Hubert Tonneau  hubert.tonneau@pliant.cx
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License version 2
# as published by the Free Software Foundation.
#
# 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
# version 2 along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

scope "/pliant/language/" "/pliant/install/"
module "/pliant/install/ring2.pli"

function general_swap a b tsize
  arg Universal a b ; arg Int tsize
  var Address pa := addressof a ; var Address pb := addressof b ; var Int remain := tsize
function general_swap a b size
  arg Universal a b ; arg Int size
  var Address pa := addressof a ; var Address pb := addressof b ; var Int remain := size
  while remain>=uInt:size
    var uInt i := pa map uInt
    pa map uInt := pb map uInt
    pb map uInt := i
    pa := pa translate uInt 1
    pb := pb translate uInt 1
    remain -= uInt size
  while remain>0
    var uInt i := pa map uInt8
    pa map uInt8 := pb map uInt8
    pb map uInt8 := i
    pa := pa translate uInt8 1
    pb := pb translate uInt8 1
    remain -= uInt8 size

meta swap e
  if e:size<>2
    return
  e:0 compile ?
  var Link:Type t :> e:0:result:type real_data_type
  if not (e:1 cast t)
    t :> e:1:result:type real_data_type
    if not (e:0 cast t)
      return
  e:0 cast t ; e:1 cast t
  if (e:0:access .and. access_write)=0 or (e:1:access .and. access_write)=0
    return
  e suckup e:0 ; e suckup e:1
  if t:size=Int:size
    var Link:Argument tmp :> argument local Int
    e add (instruction (the_function 'copy atomic' Int Int) e:0:result tmp)
    e add (instruction (the_function 'copy atomic' Int Int) e:1:result e:0:result)
    e add (instruction (the_function 'copy atomic' Int Int) tmp e:1:result)
  else
    var Link:Argument tsize :> argument constant Int t:size
    e add (instruction (the_function general_swap Universal Universal Int) e:0:result e:1:result tsize)
  e set_void_result

export swap