diff options
author | Marcin Juszkiewicz <marcin@juszkiewicz.com.pl> | 2009-09-30 15:06:17 +0200 |
---|---|---|
committer | Marcin Juszkiewicz <marcin@juszkiewicz.com.pl> | 2009-09-30 19:06:36 +0200 |
commit | a261b5ea923854b9a84f91cec0177ff57e905c98 (patch) | |
tree | 1d2563f24426102c3d6f83873349e79f288f0db3 /recipes/gcc/gcc-4.2.4/ep93xx/arm-crunch-cirrus-di-flag.patch | |
parent | fe2fa19a4a00b3c7778933c476d57ca46c303c61 (diff) |
gcc: update Maverick Crunch support to 20090908 version
From Martin W. Guy page http://martinwguy.co.uk/martin/crunch/
The 20090908 version
* performs single and double precision floating point in the FPU (add, sub,
mul, neg, abs, cmp and conversions from single and double precision floats
to integral types).
* by default, disables the floating point cfnegs and cfnegd instructions,
which fail to convert 0 to -0 as they should. You can re-enable them with
the -funsafe-math-optimizations flag, which is one of those enabled
by -ffast-math (gcc-4.3 has an even more specific -fno-signed-zeros flag,
which is one of those enabled by -funsafe-math-optimizations).
* by default, does not respect denormalised values, so the smallest
representable values are ±2-126 for floats and ±2-1022 for doubles instead of
the usual ±2-149 and ±2-1074.
* has a -mieee flag, which enables handling of denormalized values by disabling
all the buggy instructions. With this, floating point addition, subtraction,
negation, absolute value and conversion between floats and integer types are
performed in software, leaving only floating point multiplication and
comparison performed in hardware.
* has no negative impact on regular ARM code generation.
* always works round the hardware bugs in the FPU and no longer has the
-mcirrus-fix-invalid-insns flag since chip development has stopped and all
existing silicon has the same bugs except for the original revision D0 which
is not supported.
* passes GCC's IEEE testsuite except for the one specific test that checks for
correct handling of denormalized values. With -mieee it passes all the math
tests.
* passes all other testsuites that I've tried (see below) including the
stringent "paranoia" floating point IEEE conformance test.
* produces the fastest Maverick code yet: 5.94 MFLOPS according to FFTW's
tests/bench -opatient cf1024 benchmark and LAME takes 2m25 to encode that
30-second WAV file on a 200MHz EP9307 (compared to 5.4 and 2m30 for the
futaris patches for 4.1.2 and 4.2.0).
* does not use the FPU's buggy 64-bit integer instructions unless the new
-mcirrus-di flag is given. Programs that do a lot of 64-bit integer
operations (add, sub, mul, neg, abs, shifts) may be faster using this, but
rigorous testing will be necessary to ensure that bad code is not being
produced. OpenSSL's testsuite fails if this is enabled. There is more detail
at the head of the arm-crunch-cirrus-di-flag.patch file.
Known bugs
* C: Values held in Maverick registers are not restored when performing a
setjmp/longjmp pair. There is a fix to glibc for this in a message to the
linux-cirrus mailing list.
* C++: Similarly, exception unwinding (performing a throw back to a catch block
in a different function) does not restore floating point and 64-bit values
held in Maverick registers.
* C++: Some C++ files will not compile, saying
".save {mv8}" Error: register expected
although the same files will compile with optimization disabled.
There is a patch to make binutils recognize these registers in the .save
macro in a message to the linux-cirrus mailing list.
Diffstat (limited to 'recipes/gcc/gcc-4.2.4/ep93xx/arm-crunch-cirrus-di-flag.patch')
-rw-r--r-- | recipes/gcc/gcc-4.2.4/ep93xx/arm-crunch-cirrus-di-flag.patch | 299 |
1 files changed, 299 insertions, 0 deletions
diff --git a/recipes/gcc/gcc-4.2.4/ep93xx/arm-crunch-cirrus-di-flag.patch b/recipes/gcc/gcc-4.2.4/ep93xx/arm-crunch-cirrus-di-flag.patch new file mode 100644 index 0000000000..e336106a4f --- /dev/null +++ b/recipes/gcc/gcc-4.2.4/ep93xx/arm-crunch-cirrus-di-flag.patch @@ -0,0 +1,299 @@ +This patch disables all 64-bit integer operations of the MaverickCrunch unit +unless the new flag -mcirrus-di is supplied (as well as -mcpu-ep9312 +-mfpu=maverick -mfloat-abi=softfp). + +The 64-bit instructions (or their GCC support) are known to be buggy, as shown +for example by openssl-0.9.8g's testsuite: +In the unpacked openssl source directory: + $ ./config + $ vi Makefile + > /^CC= /s/$/-4.3-crunch/ + > /^CFLAG= /s/$/ -mcpu=ep9312 -mfpu=maverick -mfloat-abi=softfp -mcirrus-di/ + > :wq + $ make + $ make test +fails if either of the two files: */sha/sha512.c and */bn/bn_asm.c are compiled +with cirrus 64-bit support enabled. If you disable cfmul64, sha512.c works ok, +but I've disabled everything down to cfadd64, cfsub64 and 64-bit load and store +and bn_asm still fails, which suggests another hardware timing bug. + +Index: gcc-4.2.4/gcc/config/arm/arm.opt +=================================================================== +--- gcc-4.2.4.orig/gcc/config/arm/arm.opt 2009-08-09 16:08:54.000000000 +0100 ++++ gcc-4.2.4/gcc/config/arm/arm.opt 2009-08-09 16:08:55.000000000 +0100 +@@ -63,6 +63,10 @@ + Target Report Mask(CALLER_INTERWORKING) + Thumb: Assume function pointers may go to non-Thumb aware code + ++mcirrus-di ++Target Report Mask(CIRRUS_DI) ++Cirrus: Enable processing of 64-bit integers in the MaverickCrunch unit (buggy) ++ + mcpu= + Target RejectNegative Joined + Specify the name of the target CPU +Index: gcc-4.2.4/gcc/config/arm/arm.c +=================================================================== +--- gcc-4.2.4.orig/gcc/config/arm/arm.c 2009-08-09 16:08:54.000000000 +0100 ++++ gcc-4.2.4/gcc/config/arm/arm.c 2009-08-09 16:08:55.000000000 +0100 +@@ -12030,7 +12030,8 @@ + upper 32 bits. This causes gcc all sorts of grief. We can't + even split the registers into pairs because Cirrus SI values + get sign extended to 64bits-- aldyh. */ +- return (GET_MODE_CLASS (mode) == MODE_FLOAT) || (mode == DImode); ++ return (GET_MODE_CLASS (mode) == MODE_FLOAT) ++ || (mode == DImode && TARGET_CIRRUS_DI); + + if (TARGET_HARD_FLOAT && TARGET_VFP + && IS_VFP_REGNUM (regno)) +Index: gcc-4.2.4/gcc/config/arm/arm.md +=================================================================== +--- gcc-4.2.4.orig/gcc/config/arm/arm.md 2009-08-09 16:08:51.000000000 +0100 ++++ gcc-4.2.4/gcc/config/arm/arm.md 2009-08-09 16:08:55.000000000 +0100 +@@ -356,7 +356,7 @@ + (clobber (reg:CC CC_REGNUM))])] + "TARGET_EITHER" + " +- if (TARGET_HARD_FLOAT && TARGET_MAVERICK) ++ if (TARGET_HARD_FLOAT && TARGET_MAVERICK && TARGET_CIRRUS_DI) + { + if (!cirrus_fp_register (operands[0], DImode)) + operands[0] = force_reg (DImode, operands[0]); +@@ -392,7 +392,7 @@ + (plus:DI (match_operand:DI 1 "s_register_operand" "%0, 0") + (match_operand:DI 2 "s_register_operand" "r, 0"))) + (clobber (reg:CC CC_REGNUM))] +- "TARGET_ARM && !(TARGET_HARD_FLOAT && TARGET_MAVERICK)" ++ "TARGET_ARM && !(TARGET_HARD_FLOAT && TARGET_MAVERICK && TARGET_CIRRUS_DI)" + "#" + "TARGET_ARM && reload_completed" + [(parallel [(set (reg:CC_C CC_REGNUM) +@@ -420,7 +420,7 @@ + (match_operand:SI 2 "s_register_operand" "r,r")) + (match_operand:DI 1 "s_register_operand" "r,0"))) + (clobber (reg:CC CC_REGNUM))] +- "TARGET_ARM && !(TARGET_HARD_FLOAT && TARGET_MAVERICK)" ++ "TARGET_ARM && !(TARGET_HARD_FLOAT && TARGET_MAVERICK && TARGET_CIRRUS_DI)" + "#" + "TARGET_ARM && reload_completed" + [(parallel [(set (reg:CC_C CC_REGNUM) +@@ -449,7 +449,7 @@ + (match_operand:SI 2 "s_register_operand" "r,r")) + (match_operand:DI 1 "s_register_operand" "r,0"))) + (clobber (reg:CC CC_REGNUM))] +- "TARGET_ARM && !(TARGET_HARD_FLOAT && TARGET_MAVERICK)" ++ "TARGET_ARM && !(TARGET_HARD_FLOAT && TARGET_MAVERICK && TARGET_CIRRUS_DI)" + "#" + "TARGET_ARM && reload_completed" + [(parallel [(set (reg:CC_C CC_REGNUM) +@@ -834,7 +834,7 @@ + (clobber (reg:CC CC_REGNUM))])] + "TARGET_EITHER" + " +- if (TARGET_HARD_FLOAT && TARGET_MAVERICK ++ if (TARGET_HARD_FLOAT && TARGET_MAVERICK && TARGET_CIRRUS_DI + && TARGET_ARM + && cirrus_fp_register (operands[0], DImode) + && cirrus_fp_register (operands[1], DImode)) +@@ -2659,7 +2659,8 @@ + values to iwmmxt regs and back. */ + FAIL; + } +- else if (!TARGET_REALLY_IWMMXT && !(TARGET_HARD_FLOAT && TARGET_MAVERICK)) ++ else if (!TARGET_REALLY_IWMMXT ++ && !(TARGET_HARD_FLOAT && TARGET_MAVERICK && TARGET_CIRRUS_DI)) + FAIL; + " + ) +@@ -4166,7 +4167,8 @@ + [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r, r, r, m") + (match_operand:DI 1 "di_operand" "rDa,Db,Dc,mi,r"))] + "TARGET_ARM +- && !(TARGET_HARD_FLOAT && (TARGET_MAVERICK || TARGET_VFP)) ++ && !(TARGET_HARD_FLOAT ++ && ((TARGET_MAVERICK && TARGET_CIRRUS_DI) || TARGET_VFP)) + && !TARGET_IWMMXT + && ( register_operand (operands[0], DImode) + || register_operand (operands[1], DImode))" +@@ -4286,7 +4288,7 @@ + [(set (match_operand:DI 0 "nonimmediate_operand" "=l,l,l,l,>,l, m,*r") + (match_operand:DI 1 "general_operand" "l, I,J,>,l,mi,l,*r"))] + "TARGET_THUMB +- && !(TARGET_HARD_FLOAT && TARGET_MAVERICK) ++ && !(TARGET_HARD_FLOAT && TARGET_MAVERICK && TARGET_CIRRUS_DI) + && ( register_operand (operands[0], DImode) + || register_operand (operands[1], DImode))" + "* +Index: gcc-4.2.4/gcc/config/arm/cirrus.md +=================================================================== +--- gcc-4.2.4.orig/gcc/config/arm/cirrus.md 2009-08-09 16:08:52.000000000 +0100 ++++ gcc-4.2.4/gcc/config/arm/cirrus.md 2009-08-16 22:32:00.000000000 +0100 +@@ -85,7 +85,7 @@ + [(set (match_operand:DI 0 "cirrus_fp_register" "=v") + (plus:DI (match_operand:DI 1 "cirrus_fp_register" "v") + (match_operand:DI 2 "cirrus_fp_register" "v")))] +- "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK" ++ "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK && TARGET_CIRRUS_DI" + "cfadd64%?\\t%V0, %V1, %V2" + [(set_attr "type" "farith") + (set_attr "cirrus" "normal")] +@@ -126,7 +126,7 @@ + [(set (match_operand:DI 0 "cirrus_fp_register" "=v") + (minus:DI (match_operand:DI 1 "cirrus_fp_register" "v") + (match_operand:DI 2 "cirrus_fp_register" "v")))] +- "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK" ++ "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK && TARGET_CIRRUS_DI" + "cfsub64%?\\t%V0, %V1, %V2" + [(set_attr "type" "farith") + (set_attr "cirrus" "normal")] +@@ -176,7 +176,7 @@ + [(set (match_operand:DI 0 "cirrus_fp_register" "=v") + (mult:DI (match_operand:DI 2 "cirrus_fp_register" "v") + (match_operand:DI 1 "cirrus_fp_register" "v")))] +- "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK" ++ "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK && TARGET_CIRRUS_DI" + "cfmul64%?\\t%V0, %V1, %V2" + [(set_attr "type" "fmul") + (set_attr "cirrus" "normal")] +@@ -230,7 +230,7 @@ + (define_insn "cirrus_ashl_const" + [(set (match_operand:SI 0 "cirrus_fp_register" "=v") + (ashift:SI (match_operand:SI 1 "cirrus_fp_register" "v") +- (match_operand:SI 2 "cirrus_shift_const" "")))] ++ (match_operand:SI 2 "const_cirrus_shift_operand" "")))] + "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK && 0" + "cfsh32%?\\t%V0, %V1, #%s2" + [(set_attr "type" "farith") +@@ -240,7 +240,7 @@ + (define_insn "cirrus_ashiftrt_const" + [(set (match_operand:SI 0 "cirrus_fp_register" "=v") + (ashiftrt:SI (match_operand:SI 1 "cirrus_fp_register" "v") +- (match_operand:SI 2 "cirrus_shift_const" "")))] ++ (match_operand:SI 2 "const_cirrus_shiftrt_operand" "")))] + "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK && 0" + "cfsh32%?\\t%V0, %V1, #-%s2" + [(set_attr "type" "farith") +@@ -261,7 +261,7 @@ + [(set (match_operand:DI 0 "cirrus_fp_register" "=v") + (ashift:DI (match_operand:DI 1 "cirrus_fp_register" "v") + (match_operand:SI 2 "register_operand" "r")))] +- "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK" ++ "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK && TARGET_CIRRUS_DI" + "cfrshl64%?\\t%V1, %V0, %s2" + [(set_attr "type" "farith") + (set_attr "cirrus" "normal")] +@@ -270,8 +270,8 @@ + (define_insn "cirrus_ashldi_const" + [(set (match_operand:DI 0 "cirrus_fp_register" "=v") + (ashift:DI (match_operand:DI 1 "cirrus_fp_register" "v") +- (match_operand:SI 2 "cirrus_shift_const" "")))] +- "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK" ++ (match_operand:SI 2 "const_cirrus_shift_operand" "")))] ++ "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK && TARGET_CIRRUS_DI" + "cfsh64%?\\t%V0, %V1, #%s2" + [(set_attr "type" "farith") + (set_attr "cirrus" "normal")] +@@ -280,8 +280,8 @@ + (define_insn "cirrus_ashiftrtdi_const" + [(set (match_operand:DI 0 "cirrus_fp_register" "=v") + (ashiftrt:DI (match_operand:DI 1 "cirrus_fp_register" "v") +- (match_operand:SI 2 "cirrus_shift_const" "")))] +- "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK" ++ (match_operand:SI 2 "const_cirrus_shiftrt_operand" "")))] ++ "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK && TARGET_CIRRUS_DI" + "cfsh64%?\\t%V0, %V1, #-%s2" + [(set_attr "type" "farith") + (set_attr "cirrus" "normal")] +@@ -290,7 +290,7 @@ + (define_insn "*cirrus_absdi2" + [(set (match_operand:DI 0 "cirrus_fp_register" "=v") + (abs:DI (match_operand:DI 1 "cirrus_fp_register" "v")))] +- "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK" ++ "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK && TARGET_CIRRUS_DI" + "cfabs64%?\\t%V0, %V1" + [(set_attr "type" "farith") + (set_attr "cirrus" "normal")] +@@ -301,7 +301,7 @@ + [(set (match_operand:DI 0 "cirrus_fp_register" "=v") + (neg:DI (match_operand:DI 1 "cirrus_fp_register" "v"))) + (clobber (reg:CC CC_REGNUM))] +- "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK" ++ "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK && TARGET_CIRRUS_DI" + "cfneg64%?\\t%V0, %V1" + [(set_attr "type" "farith") + (set_attr "cirrus" "normal")] +@@ -392,7 +392,7 @@ + (define_insn "floatdisf2" + [(set (match_operand:SF 0 "cirrus_fp_register" "=v") + (float:SF (match_operand:DI 1 "cirrus_fp_register" "v")))] +- "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK" ++ "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK && TARGET_CIRRUS_DI" + "cfcvt64s%?\\t%V0, %V1" + [(set_attr "type" "f_cvt") + (set_attr "cirrus" "normal")] +@@ -401,7 +401,7 @@ + (define_insn "floatdidf2" + [(set (match_operand:DF 0 "cirrus_fp_register" "=v") + (float:DF (match_operand:DI 1 "cirrus_fp_register" "v")))] +- "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK" ++ "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK && TARGET_CIRRUS_DI" + "cfcvt64d%?\\t%V0, %V1" + [(set_attr "type" "f_cvt") + (set_attr "cirrus" "normal")] +@@ -454,7 +454,7 @@ + (define_insn "*cirrus_arm_movdi" + [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r,r,o<>,v,r,v,m,v") + (match_operand:DI 1 "di_operand" "rIK,mi,r,r,v,mi,v,v"))] +- "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK" ++ "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK && TARGET_CIRRUS_DI" + "* + { + switch (which_alternative) +Index: gcc-4.2.4/gcc/doc/invoke.texi +=================================================================== +--- gcc-4.2.4.orig/gcc/doc/invoke.texi 2009-08-09 16:08:54.000000000 +0100 ++++ gcc-4.2.4/gcc/doc/invoke.texi 2009-08-09 16:08:55.000000000 +0100 +@@ -417,6 +417,7 @@ + -msingle-pic-base -mno-single-pic-base @gol + -mpic-register=@var{reg} @gol + -mnop-fun-dllimport @gol ++-mirrus-di @gol + -mieee @gol + -mpoke-function-name @gol + -mthumb -marm @gol +@@ -7770,6 +7771,16 @@ + Specify the register to be used for PIC addressing. The default is R10 + unless stack-checking is enabled, when R9 is used. + ++@item -mcirrus-di ++When compiling for the Maverick FPU, enable handling of 64-bit integers ++in the FPU (add, subtract, multiply, arithmetic shifts and conversions). ++Normally they are disabled because some instruction sequences can give ++erroneous results. ++This option only has any effect if the ++@option{-mcpu=ep9312} @option{-mfpu=maverick} options have been used and is ++disabled by default. ++The default can be re-enabled by use of the @option{-mno-cirrus-di} switch. ++ + @item -mieee + When compiling for the Maverick FPU, disable the instructions that fail + to honor denormalized values. As these include floating point add, sub, +Index: gcc-4.2.4/gcc/config/arm/predicates.md +=================================================================== +--- gcc-4.2.4.orig/gcc/config/arm/predicates.md 2009-08-16 22:27:01.000000000 +0100 ++++ gcc-4.2.4/gcc/config/arm/predicates.md 2009-08-16 22:29:15.000000000 +0100 +@@ -460,8 +460,12 @@ + || REGNO_REG_CLASS (REGNO (op)) == CIRRUS_REGS)); + }) + +-(define_predicate "cirrus_shift_const" ++(define_predicate "const_cirrus_shift_operand" + (and (match_code "const_int") +- (match_test "((unsigned HOST_WIDE_INT) INTVAL (op)) < 64"))) ++ (match_test "((unsigned HOST_WIDE_INT) INTVAL (op)) <= 31"))) ++ ++(define_predicate "const_cirrus_shiftrt_operand" ++ (and (match_code "const_int") ++ (match_test "((unsigned HOST_WIDE_INT) INTVAL (op)) <= 32"))) + + |