"Tobias Burnus" <
bur...@net-b.de> wrote in message
news:5029EDEE...@net-b.de...
I was looking at
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40210
And it seemed to me that either
C:\gfortran\clf\bswap>type bswap.f90
module builtins
use ISO_C_BINDING
implicit none
private
public bswap, bswap16, bswap32, bswap64, bswap128
interface bswap
function bswap32(x) bind(C,name='__builtin_bswap32')
import
implicit none
integer(C_INT32_T) bswap32
integer(C_INT32_T), value :: x
end function bswap32
function bswap64(x) bind(C,name='__builtin_bswap64')
import
implicit none
integer(C_INT64_T) bswap64
integer(C_INT64_T), value :: x
end function bswap64
module procedure bswap16, bswap128
end interface bswap
contains
function bswap16(x)
integer(C_INT16_T) bswap16
integer(C_INT16_T), value :: x
bswap16 = ishftc(x,8)
end function bswap16
function bswap128(x)
integer(C_INT128_T) bswap128
integer(C_INT128_T), value :: x
bswap128 = ior( &
ishft(int(bswap64(int(x,C_INT64_T)),C_INT128_T),64), &
int(bswap64(int(ishft(x,-64),C_INT64_T)),C_INT128_T))
end function bswap128
end module builtins
module testmod
contains
function test16(x)
use builtins
use ISO_C_BINDING
implicit none
integer(C_INT16_T) test16
integer(C_INT16_T), value :: x
test16 = bswap(x)
end function test16
function test32(x)
use builtins
use ISO_C_BINDING
implicit none
integer(C_INT32_T) test32
integer(C_INT32_T), value :: x
test32 = bswap(x)
end function test32
function test64(x)
use builtins
use ISO_C_BINDING
implicit none
integer(C_INT64_T) test64
integer(C_INT64_T), value :: x
test64 = bswap(x)
end function test64
function test128(x)
use builtins
use ISO_C_BINDING
implicit none
integer(C_INT128_T) test128
integer(C_INT128_T), value :: x
test128 = bswap(x)
end function test128
end module testmod
program test
use ISO_C_BINDING
use testmod
implicit none
integer(C_INT16_T) :: x16 = 1
integer(C_INT32_T) :: x32 = 1
integer(C_INT64_T) :: x64 = 1
integer(C_INT128_T) :: x128 = 1
write(*,*) test16(x16)+test32(x32)+test64(x64)+test128(x128)
end program test
C:\gfortran\clf\bswap>gfortran bswap.f90 -obswap
C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\ccAbEXSA.o:bswap.f90:(.text+0x1d):
undefined
reference to `__builtin_bswap64'
C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\ccAbEXSA.o:bswap.f90:(.text+0x44):
undefined
reference to `__builtin_bswap64'
C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\ccAbEXSA.o:bswap.f90:(.text+0x105):
undefined
reference to `__builtin_bswap64'
C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\ccAbEXSA.o:bswap.f90:(.text+0x126):
undefined
reference to `__builtin_bswap32'
c:/gcc_equation/bin/../lib/gcc/x86_64-w64-mingw32/4.8.0/../../../../x86_64-w64-m
ingw32/bin/ld.exe: C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\ccAbEXSA.o: bad reloc
addr
ess 0x0 in section `.pdata'
c:/gcc_equation/bin/../lib/gcc/x86_64-w64-mingw32/4.8.0/../../../../x86_64-w64-m
ingw32/bin/ld.exe: final link failed: Invalid operation
collect2.exe: error: ld returned 1 exit status
or
C:\gfortran\clf\bswap>type bswap2.f90
module test
use ISO_C_BINDING
implicit none
contains
function bswap32(x) bind(C,name='bswap32')
integer(C_INT32_T) bswap32
integer(C_INT32_T), value :: x
bswap32 = ior(ior(ior( &
ishft(iand(x,int(Z'000000FF',C_INT32_T)),24), &
ishft(iand(x,int(Z'0000FF00',C_INT32_T)),8)), &
ishft(iand(x,int(Z'00FF0000',C_INT32_T)),-8)), &
ishft(iand(x,int(Z'FF000000',C_INT32_T)),-24))
end function bswap32
function bswap64(x) bind(C,name='bswap64')
integer(C_INT64_T) bswap64
integer(C_INT64_T), value :: x
bswap64 = ior(ior(ior(ior(ior(ior(ior( &
ishft(iand(x,int(Z'00000000000000FF',C_INT64_T)),56), &
ishft(iand(x,int(Z'000000000000FF00',C_INT64_T)),40)), &
ishft(iand(x,int(Z'0000000000FF0000',C_INT64_T)),24)), &
ishft(iand(x,int(Z'00000000FF000000',C_INT64_T)),8)), &
ishft(iand(x,int(Z'000000FF00000000',C_INT64_T)),-8)), &
ishft(iand(x,int(Z'0000FF0000000000',C_INT64_T)),-24)), &
ishft(iand(x,int(Z'00FF000000000000',C_INT64_T)),-40)), &
ishft(iand(x,int(Z'FF00000000000000',C_INT64_T)),-56))
end function bswap64
end module test
program main
use test
implicit none
integer(C_INT32_T) :: x32 = 1
integer(C_INT64_T) :: x64 = 1
write(*,*) bswap32(x32)+bswap64(x64)
end program main
C:\gfortran\clf\bswap>gfortran -fno-range-check -O3 -mtune=native -march=native
-fomit-frame-pointer bswap2.f90 -S
C:\gfortran\clf\bswap>type bswap2.s
.file "bswap2.f90"
.text
.p2align 4,,15
.globl bswap64
.def bswap64; .scl 2; .type 32; .endef
.seh_proc bswap64
bswap64:
.seh_endprologue
movq %rcx, %rax
movq %rcx, %rdx
andl $65280, %eax
salq $56, %rdx
salq $40, %rax
orq %rdx, %rax
movq %rcx, %rdx
andl $16711680, %edx
salq $24, %rdx
orq %rdx, %rax
movq %rcx, %rdx
andl $4278190080, %edx
salq $8, %rdx
orq %rdx, %rax
movq %rcx, %rdx
shrq $8, %rdx
andl $4278190080, %edx
orq %rdx, %rax
movq %rcx, %rdx
shrq $24, %rdx
andl $16711680, %edx
orq %rdx, %rax
movq %rcx, %rdx
shrq $56, %rcx
shrq $40, %rdx
andl $65280, %edx
orq %rdx, %rax
orq %rcx, %rax
ret
.seh_endproc
.section .rdata,"dr"
.LC0:
.ascii "bswap2.f90\0"
.text
.p2align 4,,15
.def MAIN__; .scl 3; .type 32; .endef
.seh_proc MAIN__
MAIN__:
subq $536, %rsp
.seh_stackalloc 536
.seh_endprologue
leaq .LC0(%rip), %rax
leaq 48(%rsp), %rcx
movq %rax, 56(%rsp)
movl $35, 64(%rsp)
movl $128, 48(%rsp)
movl $6, 52(%rsp)
call _gfortran_st_write
movl $1, %ecx
call bswap64
leaq 40(%rsp), %rdx
movl $8, %r8d
leaq 48(%rsp), %rcx
addq $16777216, %rax
movq %rax, 40(%rsp)
call _gfortran_transfer_integer_write
leaq 48(%rsp), %rcx
call _gfortran_st_write_done
nop
addq $536, %rsp
ret
.seh_endproc
.p2align 4,,15
.globl bswap32
.def bswap32; .scl 2; .type 32; .endef
.seh_proc bswap32
bswap32:
.seh_endprologue
movl %ecx, %eax
movl %ecx, %edx
andl $65280, %eax
sall $24, %edx
sall $8, %eax
orl %edx, %eax
movl %ecx, %edx
shrl $24, %ecx
andl $16711680, %edx
shrl $8, %edx
orl %edx, %eax
orl %ecx, %eax
ret
.seh_endproc
.def __main; .scl 2; .type 32; .endef
.section .text.startup,"x"
.p2align 4,,15
.globl main
.def main; .scl 2; .type 32; .endef
.seh_proc main
main:
pushq %rsi
.seh_pushreg %rsi
pushq %rbx
.seh_pushreg %rbx
subq $40, %rsp
.seh_stackalloc 40
.seh_endprologue
movl %ecx, %ebx
movq %rdx, %rsi
call __main
movq %rsi, %rdx
movl %ebx, %ecx
call _gfortran_set_args
leaq options.1.1878(%rip), %rdx
movl $7, %ecx
call _gfortran_set_options
call MAIN__
xorl %eax, %eax
addq $40, %rsp
popq %rbx
popq %rsi
ret
.seh_endproc
.section .rdata,"dr"
.align 16
options.1.1878:
.long 68
.long 1023
.long 0
.long 0
.long 1
.long 1
.long 0
.def _gfortran_st_write; .scl 2; .type 32;
.endef
.def _gfortran_transfer_integer_write; .scl 2;
.type
32; .endef
.def _gfortran_st_write_done; .scl 2; .type 32;
.endef
.def _gfortran_set_args; .scl 2; .type 32;
.endef
.def _gfortran_set_options; .scl 2; .type 32;
.endef
should work, but neither did, the first because gfortran couldn't
figure out __builtin_bswap* and the second because gfortran wasn't
as alert as gcc at determining when to use a bswap instruction.
Can you get either or both of these examples to work in gfortran?
--
write(*,*) transfer((/17.392111325966148d0,6.5794487871554595D-85, &
6.0134700243160014d-154/),(/'x'/)); end