1################################################################################ 2# 3# PROGRAM: arch.pl 4# 5################################################################################ 6# 7# DESCRIPTION: Generate header file for architecture specific definitions 8# 9################################################################################ 10# 11# Copyright (c) 2002-2020 Marcus Holland-Moritz. All rights reserved. 12# This program is free software; you can redistribute it and/or modify 13# it under the same terms as Perl itself. 14# 15################################################################################ 16 17use Config; 18 19$file = @ARGV ? shift : 'ctlib/arch.h'; 20open OUT, ">$file" or die "$file: $!\n"; 21 22%cfg = %Config; # because we modify some values in %cfg 23 24%use = ( 25 '64BIT' => 1, 26 'LONGLONG' => 1, 27 'LONGDOUBLE' => 1, 28); 29 30if( $Config{osname} eq 'hpux' and $Config{cc} eq 'cc' and 31 $Config{osvers} =~ /(\d+)\.(\d+)/ and $1 < 11 ) { 32 # At least some versions of HP's cc compiler have a broken 33 # preprocessor/compiler implementation of 64-bit data types. 34 $use{'64BIT'} = 0; 35 $use{'LONGLONG'} = 0; 36} 37 38for( keys %use ) { 39 exists $ENV{"CBC_USE$_"} and $use{$_} = $ENV{"CBC_USE$_"}; 40} 41 42# <HACK> required to support perl < 5.6.0 43 44unless( exists $cfg{i8type} ) { 45 $b8 = 'char'; 46 47 for( qw( int short long ) ) { 48 if( not defined $b16 and $cfg{"${_}size"} == 2 ) { $b16 = $_ } 49 if( not defined $b32 and $cfg{"${_}size"} == 4 ) { $b32 = $_ } 50 } 51 52 defined $b16 and defined $b32 or die "cannot determine integer sizes"; 53 54 $cfg{i8type} = "signed $b8"; 55 $cfg{u8type} = "unsigned $b8"; 56 $cfg{i16type} = "signed $b16"; 57 $cfg{u16type} = "unsigned $b16"; 58 $cfg{i32type} = "signed $b32"; 59 $cfg{u32type} = "unsigned $b32"; 60} 61 62# </HACK> 63 64# make the i_8 explicitly signed 65# (i8type was plain 'char' on an IPAQ system where 'char' was unsigned) 66if( $cfg{i8type} eq 'char' ) { 67 $cfg{i8type} = 'signed char'; 68} 69 70sub is_big_endian () 71{ 72 my $byteorder = $cfg{byteorder} 73 || unpack( "a*", pack "L", 0x34333231 ); 74 75 die "Native byte order ($byteorder) not supported!\n" 76 if $byteorder ne '1234' and $byteorder ne '4321' 77 and $byteorder ne '12345678' and $byteorder ne '87654321'; 78 79 $byteorder eq '4321' or $byteorder eq '87654321'; 80} 81 82sub config ($) { 83 local $_ = shift; 84 s/\$\{([^}]+)\}/$cfg{$1}/g; 85 print OUT; 86} 87 88$long_double = $use{LONGDOUBLE} && $cfg{d_longdbl} eq 'define' ? 1 : 0; 89print "DISABLED long double support\n" if $use{LONGDOUBLE} == 0; 90 91$long_long = $use{LONGLONG} && $cfg{d_longlong} eq 'define' ? 1 : 0; 92print "DISABLED long long support\n" if $use{LONGLONG} == 0; 93 94config <<ENDCFG; 95#ifndef _CTLIB_ARCH_H 96#define _CTLIB_ARCH_H 97 98#define ARCH_HAVE_LONG_DOUBLE $long_double 99#define ARCH_HAVE_LONG_LONG $long_long 100ENDCFG 101 102if( $use{'64BIT'} && $cfg{d_quad} eq 'define' ) { 103config <<'ENDCFG'; 104#define ARCH_NATIVE_64_BIT_INTEGER 1 105 106/* 64-bit integer data types */ 107typedef ${i64type} i_64; 108typedef ${u64type} u_64; 109 110ENDCFG 111} 112elsif( $use{'64BIT'} && $cfg{d_longlong} eq 'define' and $cfg{longlongsize} == 8 ) { 113config <<'ENDCFG'; 114#define ARCH_NATIVE_64_BIT_INTEGER 1 115 116/* 64-bit integer data types */ 117typedef signed long long i_64; 118typedef unsigned long long u_64; 119 120ENDCFG 121} 122else { 123 print "DISABLED 64-bit support\n" if $use{'64BIT'} == 0; 124config <<'ENDCFG'; 125#define ARCH_NATIVE_64_BIT_INTEGER 0 126 127/* no native 64-bit support */ 128typedef struct { 129 ${u32type} h; 130 ${u32type} l; 131} u_64; 132 133typedef struct { 134 ${i32type} h; 135 ${u32type} l; 136} i_64; 137 138ENDCFG 139} 140 141$byteorder = is_big_endian ? 'BIG' : 'LITTLE'; 142 143config <<"ENDCFG"; 144#define ARCH_BYTEORDER_BIG_ENDIAN 1 145#define ARCH_BYTEORDER_LITTLE_ENDIAN 2 146#define ARCH_NATIVE_BYTEORDER ARCH_BYTEORDER_${byteorder}_ENDIAN 147 148ENDCFG 149 150config <<'ENDCFG'; 151/* 32-bit integer data types */ 152typedef ${i32type} i_32; 153typedef ${u32type} u_32; 154 155/* 16-bit integer data types */ 156typedef ${i16type} i_16; 157typedef ${u16type} u_16; 158 159/* 8-bit integer data types */ 160typedef ${i8type} i_8; 161typedef ${u8type} u_8; 162 163ENDCFG 164 165config <<'ENDCFG'; 166#endif 167ENDCFG 168 169close OUT; 170