From b19d1bd16a7d9db22a84af3d2321a5b34150a8a0 Mon Sep 17 00:00:00 2001 From: Markus Scherer Date: Thu, 1 Dec 2011 06:04:35 +0000 Subject: [PATCH] ICU-8915 flag & test for whether signed integer right shift is Arithmetic Shift Right X-SVN-Rev: 30999 --- icu4c/source/common/normalizer2impl.cpp | 5 ++++ icu4c/source/common/putilimp.h | 31 +++++++++++++++++++++++++ icu4c/source/test/cintltst/putiltst.c | 19 ++++++++++++++- 3 files changed, 54 insertions(+), 1 deletion(-) diff --git a/icu4c/source/common/normalizer2impl.cpp b/icu4c/source/common/normalizer2impl.cpp index e1c137d482d..ecbefdc6fcd 100644 --- a/icu4c/source/common/normalizer2impl.cpp +++ b/icu4c/source/common/normalizer2impl.cpp @@ -1008,7 +1008,12 @@ Normalizer2Impl::composePair(UChar32 a, UChar32 b) const { if(b<0 || 0x10ffff>1; +#else + int32_t compositeAndFwd=combine(list, b); + return compositeAndFwd>=0 ? compositeAndFwd>>1 : U_SENTINEL; +#endif } // Very similar to composeQuickCheck(): Make the same changes in both places if relevant. diff --git a/icu4c/source/common/putilimp.h b/icu4c/source/common/putilimp.h index 1e324913c27..6d97dacfd17 100644 --- a/icu4c/source/common/putilimp.h +++ b/icu4c/source/common/putilimp.h @@ -19,6 +19,37 @@ #include "unicode/utypes.h" #include "unicode/putil.h" +/** + * \def U_SIGNED_RIGHT_SHIFT_IS_ARITHMETIC + * Nearly all CPUs and compilers implement a right-shift of a signed integer + * as an Arithmetic Shift Right which copies the sign bit (the Most Significant Bit (MSB)) + * into the vacated bits (sign extension). + * For example, (int32_t)0xfff5fff3>>4 becomes 0xffff5fff and -1>>1=-1. + * + * This can be useful for storing a signed value in the upper bits + * and another bit field in the lower bits. + * The signed value can be retrieved by simple right-shifting. + * + * This is consistent with the Java language. + * + * However, the C standard allows compilers to implement a right-shift of a signed integer + * as a Logical Shift Right which copies a 0 into the vacated bits. + * For example, (int32_t)0xfff5fff3>>4 becomes 0x0fff5fff and -1>>1=0x7fffffff. + * + * Code that depends on the natural behavior should be guarded with this macro, + * with an alternate path for unusual platforms. + * @internal + */ +#ifdef U_SIGNED_RIGHT_SHIFT_IS_ARITHMETIC + /* Use the predefined value. */ +#else + /* + * Nearly all CPUs & compilers implement a right-shift of a signed integer + * as an Arithmetic Shift Right (with sign extension). + */ +# define U_SIGNED_RIGHT_SHIFT_IS_ARITHMETIC 1 +#endif + /** Define this to 1 if your platform supports IEEE 754 floating point, to 0 if it does not. */ #ifndef IEEE_754 diff --git a/icu4c/source/test/cintltst/putiltst.c b/icu4c/source/test/cintltst/putiltst.c index d4a3a466608..8d18f6cf562 100644 --- a/icu4c/source/test/cintltst/putiltst.c +++ b/icu4c/source/test/cintltst/putiltst.c @@ -25,6 +25,23 @@ #include "uinvchar.h" #include +/* See the comments on U_SIGNED_RIGHT_SHIFT_IS_ARITHMETIC. */ +static void TestSignedRightShiftIsArithmetic() { + int32_t x=0xfff5fff3; + int32_t m=-1; + int32_t x4=x>>4; + int32_t m1=m>>1; + UBool signedRightShiftIsArithmetic= x4==0xffff5fff && m1==-1; + if(signedRightShiftIsArithmetic==U_SIGNED_RIGHT_SHIFT_IS_ARITHMETIC) { + log_info("signed right shift is Arithmetic Shift Right: %d\n", + signedRightShiftIsArithmetic); + } else { + log_err("error: unexpected signed right shift is Arithmetic Shift Right: %d\n" + " You need to change the value of U_SIGNED_RIGHT_SHIFT_IS_ARITHMETIC " + "for your platform.\n", + signedRightShiftIsArithmetic); + } +} static UBool compareWithNAN(double x, double y); static void doAssert(double expect, double got, const char *message); @@ -192,7 +209,6 @@ static void TestVersion(void) char versionString[17]; /* xxx.xxx.xxx.xxx\0 */ UChar versionUString[] = { 0x0031, 0x002E, 0x0030, 0x002E, 0x0032, 0x002E, 0x0038, 0x0000 }; /* 1.0.2.8 */ - UBool isModified = FALSE; UVersionInfo version; UErrorCode status = U_ZERO_ERROR; @@ -674,6 +690,7 @@ static void toolutil_findDirname(void) static void addToolUtilTests(TestNode** root) { addTest(root, &toolutil_findBasename, "putiltst/toolutil/findBasename"); addTest(root, &toolutil_findDirname, "putiltst/toolutil/findDirname"); + addTest(root, &TestSignedRightShiftIsArithmetic, "putiltst/toolutil/TestSignedRightShiftIsArithmetic"); /* Not yet tested: -- 2.40.0