Browse Source

* adjusted tcalext6 and tcext6.c so libgcc is no longer required on most
non-x86 architectures

git-svn-id: trunk@15377 -

Jonas Maebe 15 years ago
parent
commit
6b5db62a5a

BIN
tests/test/cg/obj/darwin/i386/tcext6.o


BIN
tests/test/cg/obj/darwin/powerpc/tcext6.o


BIN
tests/test/cg/obj/darwin/powerpc64/tcext6.o


BIN
tests/test/cg/obj/darwin/x86_64/tcext6.o


BIN
tests/test/cg/obj/linux/arm-eabi/tcext6.o


BIN
tests/test/cg/obj/linux/i386/tcext6.o


BIN
tests/test/cg/obj/linux/x86_64/tcext6.o


+ 138 - 9
tests/test/cg/obj/tcext6.c

@@ -99,6 +99,134 @@ struct struct31 {
   float v2;
   float v2;
   };
   };
 
 
+
+/* to avoid depending on libc for double->int64 conversions
+
+License/credit:
+
+Written by John R. Hauser.  This work was made possible in part by the
+International Computer Science Institute, located at Suite 600, 1947 Center
+Street, Berkeley, California 94704.  Funding was partially provided by the
+National Science Foundation under grant MIP-9311980.  The original version
+of this code was written as part of a project to build a fixed-point vector
+processor in collaboration with the University of California at Berkeley,
+overseen by Profs. Nelson Morgan and John Wawrzynek.  More information
+is available through the Web page `http://www.cs.berkeley.edu/~jhauser/
+arithmetic/SoftFloat.html'.
+
+THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort has
+been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES
+RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS
+AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES,
+COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE
+EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE
+INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR
+OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE.
+
+Derivative works are acceptable, even for commercial purposes, so long as
+(1) the source code for the derivative work includes prominent notice that
+the work is derivative, and (2) the source code includes prominent notice with
+these four paragraphs for those parts of this code that are retained.
+
+
+*/
+
+#define LIT64( a ) a##LL
+
+#define double2float64( a ) (*(float64*)&(a))
+
+typedef char flag;
+
+typedef int64_t float64;
+typedef uint64_t bits64;
+typedef int64_t sbits64;
+
+bits64 extractFloat64Frac( float64 a )
+{
+    return a & LIT64( 0x000FFFFFFFFFFFFF );
+}
+
+int16_t extractFloat64Exp( float64 a )
+{
+    return ( a>>52 ) & 0x7FF;
+}
+
+flag extractFloat64Sign( float64 a )
+{
+    return a>>63;
+}
+
+int32_t int64_is_zero(bits64 a0)
+{
+  return (((uint32_t)(a0 >> 32)) == 0) && ((((uint32_t)(a0 & LIT64(0xFFFFFFFF)))) == 0);
+}
+
+void shift64ExtraRightJamming(bits64 a0, bits64 a1, int16_t count, bits64 *z0Ptr, bits64 *z1Ptr )
+{
+    bits64 z0, z1;
+    int8_t negCount = ( - count ) & 63;
+
+    if ( count == 0 ) {
+        z1 = a1;
+        z0 = a0;
+    }
+    else if ( count < 64 ) {
+        z1 = ( a0<<negCount ) | ( !int64_is_zero(a1));
+        z0 = a0>>count;
+    }
+    else {
+        if ( count == 64 ) {
+            z1 = a0 | ( !int64_is_zero(a1) );
+        }
+        else {
+            z1 = ( !int64_is_zero( a0 | a1 ) );
+        }
+        z0 = 0;
+    }
+    *z1Ptr = z1;
+    *z0Ptr = z0;
+}
+
+static int64_t roundAndPackInt64( flag zSign, bits64 absZ0, bits64 absZ1 )
+{
+    int64_t z;
+
+    z = absZ0;
+    if ( zSign ) z = - z;
+    return z;
+
+}
+
+int64_t float64_to_int64( float64 a )
+{
+    flag aSign;
+    int16_t aExp, shiftCount;
+    bits64 aSig, aSigExtra;
+
+    aSig = extractFloat64Frac( a );
+    aExp = extractFloat64Exp( a );
+    aSign = extractFloat64Sign( a );
+    if ( aExp ) aSig |= LIT64( 0x0010000000000000 );
+    shiftCount = 0x433 - aExp;
+    if ( shiftCount <= 0 ) {
+        if ( 0x43E < aExp ) {
+            if (    ! aSign
+                 || (    ( aExp == 0x7FF )
+                      && ( aSig != LIT64( 0x0010000000000000 ) ) )
+               ) {
+                return LIT64( 0x7FFFFFFFFFFFFFFF );
+            }
+            return (sbits64) LIT64( 0x8000000000000000 );
+        }
+        aSigExtra = 0;
+        aSig <<= - shiftCount;
+    }
+    else {
+        shift64ExtraRightJamming( aSig, 0, shiftCount, &aSig, &aSigExtra );
+    }
+    return roundAndPackInt64( aSign, aSig, aSigExtra );
+}
+
 float pass1(struct struct1 s) {
 float pass1(struct struct1 s) {
   return s.v;
   return s.v;
 }
 }
@@ -132,31 +260,31 @@ double pass8(struct struct8 s) {
 }
 }
 
 
 int64_t pass9(struct struct9 s) {
 int64_t pass9(struct struct9 s) {
-  return s.v1 + (int64_t)s.v2;
+  return s.v1 + double2float64(s.v2);
 }
 }
 
 
 int64_t pass10(struct struct10 s) {
 int64_t pass10(struct struct10 s) {
-  return s.v1 + s.v2 + (int64_t)s.v3;
+  return s.v1 + s.v2 + double2float64(s.v3);
 }
 }
 
 
 int64_t pass11(struct struct11 s) {
 int64_t pass11(struct struct11 s) {
-  return s.v1 + (int64_t)s.v2;
+  return s.v1 + double2float64(s.v2);
 }
 }
 
 
 int64_t pass12(struct struct12 s) {
 int64_t pass12(struct struct12 s) {
-  return s.v1 + (int64_t)s.v2 + (int64_t)s.v3;
+  return s.v1 + double2float64(s.v2) + double2float64(s.v3);
 }
 }
 
 
 int64_t pass13(struct struct13 s) {
 int64_t pass13(struct struct13 s) {
-  return (int64_t)s.v1 + s.v2;
+  return double2float64(s.v1) + s.v2;
 }
 }
 
 
 int64_t pass14(struct struct14 s) {
 int64_t pass14(struct struct14 s) {
-  return (int64_t)s.v1 + s.v2 + s.v3;
+  return double2float64(s.v1) + s.v2 + s.v3;
 }
 }
 
 
 int64_t pass15(struct struct15 s) {
 int64_t pass15(struct struct15 s) {
-  return (int64_t)s.v1 + s.v2 + (int64_t)s.v3;
+  return double2float64(s.v1) + s.v2 + double2float64(s.v3);
 }
 }
 
 
 float pass16(struct struct16 s) {
 float pass16(struct struct16 s) {
@@ -167,8 +295,9 @@ float pass17(struct struct17 s) {
   return s.v1 + s.v2;
   return s.v1 + s.v2;
 }
 }
 
 
-long double pass31(struct struct31 s) {
-  return s.v1 + s.v2;
+long double pass31(struct struct31 s, float *v2) {
+  *v2 = s.v2;
+  return s.v1;
 }
 }
 
 
 
 

+ 20 - 6
tests/test/cg/tcalext6.pp

@@ -14,6 +14,11 @@ program calext6;
   {$define NO_FLOAT}
   {$define NO_FLOAT}
 {$endif}
 {$endif}
 
 
+{$ifdef CPUARMEL}
+{ for softfloat calls in the C code }
+{$linklib gcc}
+{$endif}
+
 type
 type
   int8_t = shortint;
   int8_t = shortint;
   pint8_t = ^int8_t;
   pint8_t = ^int8_t;
@@ -156,6 +161,7 @@ begin
     WriteLn('Failed');
     WriteLn('Failed');
 end;
 end;
 
 
+{$ifdef FPC_HAS_TYPE_EXTENDED}
 procedure verify(val1, val2 : cextended; nr : Integer); overload;
 procedure verify(val1, val2 : cextended; nr : Integer); overload;
 begin
 begin
   success := success and (val1 = val2);
   success := success and (val1 = val2);
@@ -165,6 +171,7 @@ begin
   else
   else
     WriteLn('Failed');
     WriteLn('Failed');
 end;
 end;
+{$endif FPC_HAS_TYPE_EXTENDED}
 
 
 function check1(s : struct1) : single;
 function check1(s : struct1) : single;
 begin
 begin
@@ -253,7 +260,9 @@ end;
 
 
 function check31(s : struct31) : cextended;
 function check31(s : struct31) : cextended;
 begin
 begin
-  result := s.v1 + s.v2;
+  {Êdon't perform an addition, because that causes the C code to depend on
+    libgcc }
+  result := s.v1;
 end;
 end;
 
 
 
 
@@ -277,7 +286,7 @@ function pass15(s : struct15; b: byte) : int64_t; cdecl; external;
 function pass16(s : struct16; b: byte) : single; cdecl; external;
 function pass16(s : struct16; b: byte) : single; cdecl; external;
 function pass17(s : struct17; b: byte) : single; cdecl; external;
 function pass17(s : struct17; b: byte) : single; cdecl; external;
 {$ifdef FPC_HAS_TYPE_EXTENDED}
 {$ifdef FPC_HAS_TYPE_EXTENDED}
-function pass31(s : struct31; b: byte) : cextended; cdecl; external;
+function pass31(s : struct31; b: byte; var ss: single) : cextended; cdecl; external;
 {$endif}
 {$endif}
 
 
 function pass1a(b: byte; s : struct1) : struct1; cdecl; external;
 function pass1a(b: byte; s : struct1) : struct1; cdecl; external;
@@ -298,7 +307,7 @@ function pass15a(b: byte; s : struct15) : struct15; cdecl; external;
 function pass16a(b: byte; s : struct16) : struct16; cdecl; external;
 function pass16a(b: byte; s : struct16) : struct16; cdecl; external;
 function pass17a(b: byte; s : struct17) : struct17; cdecl; external;
 function pass17a(b: byte; s : struct17) : struct17; cdecl; external;
 {$ifdef FPC_HAS_TYPE_EXTENDED}
 {$ifdef FPC_HAS_TYPE_EXTENDED}
-function pass31a(b: byte; s : struct31) : struct31; cdecl; external;
+function pass31a(b: byte; s : struct31; var ss: single) : struct31; cdecl; external;
 {$endif}
 {$endif}
 
 
 procedure dotest;
 procedure dotest;
@@ -321,6 +330,8 @@ var
   s16 : struct16;
   s16 : struct16;
   s17 : struct17;
   s17 : struct17;
   s31 : struct31;
   s31 : struct31;
+  
+  ss: single;
 
 
 begin
 begin
   success := true;
   success := true;
@@ -403,7 +414,8 @@ begin
   verify(pass16(s16,16), check16(s16), 16);
   verify(pass16(s16,16), check16(s16), 16);
   verify(pass17(s17,17), check17(s17), 17);
   verify(pass17(s17,17), check17(s17), 17);
 {$ifdef FPC_HAS_TYPE_EXTENDED}
 {$ifdef FPC_HAS_TYPE_EXTENDED}
-  verify(pass31(s31,31), check31(s31), 31);
+  verify(pass31(s31,31,ss), check31(s31), 31);
+  verify(ss,s31.v2,32);
 {$endif}
 {$endif}
 
 
   verify(check1(pass1a(1,s1)), check1(s1), 41);
   verify(check1(pass1a(1,s1)), check1(s1), 41);
@@ -424,7 +436,8 @@ begin
   verify(check16(pass16a(16,s16)), check16(s16), 56);
   verify(check16(pass16a(16,s16)), check16(s16), 56);
   verify(check17(pass17a(17,s17)), check17(s17), 57);
   verify(check17(pass17a(17,s17)), check17(s17), 57);
 {$ifdef FPC_HAS_TYPE_EXTENDED}
 {$ifdef FPC_HAS_TYPE_EXTENDED}
-  verify(check31(pass31a(31,s31)), check31(s31), 71);
+  verify(check31(pass31a(31,s31,ss)), check31(s31), 71);
+  verify(ss,s31.v2,72);
 {$endif}
 {$endif}
 
 
   verify(pass1a(1,s1).v, s1.v, 81);
   verify(pass1a(1,s1).v, s1.v, 81);
@@ -448,7 +461,8 @@ begin
   verify(pass16a(16,s16).v1, s16.v1, 96);
   verify(pass16a(16,s16).v1, s16.v1, 96);
   verify(pass17a(17,s17).v1, s17.v1, 97);
   verify(pass17a(17,s17).v1, s17.v1, 97);
 {$ifdef FPC_HAS_TYPE_EXTENDED}
 {$ifdef FPC_HAS_TYPE_EXTENDED}
-  verify(pass31a(31,s31).v1, s31.v1, 101);
+  verify(pass31a(31,s31,ss).v1, s31.v1, 101);
+  verify(ss,s31.v2,102);
 {$endif}
 {$endif}
 
 
 {$endif ndef nofloat}
 {$endif ndef nofloat}