Committed: target/14471, workaround for errata for CRIS mul insns.
Hans-Peter Nilsson
hans-peter.nilsson@axis.com
Mon Mar 8 01:06:00 GMT 2004
See PR for more. I'll also make libstdc++-v3 be compiled
-mno-mul-bug-workaround on main trunk for non-C-libraries and
cris-*-linux*.
By the way, looks like nobody did "make dvi" for a while; it
breaks due to exceeding TeX limits with "TeX (Web2C 7.3.1)
3.14159" (stock in RH 9). To check this doc patch, I worked
around it by removing everything inside the "@ifset INTERNALS"
in md.texi. Film at 11.
Tested cross to cris-axis-elf, no regressions.
Checked in on trunk, 3.3 (except the configure stuff) and 3.4
PR target/14471
* configure.ac (Target-specific assembler checks) <cris-*-*>: New
case, checking for -no-mul-bug-abort option.
* configure, config.in: Regenerate.
* doc/invoke.texi (CRIS Options): Document -mmul-bug-workaround
and -mno-mul-bug-workaround.
* config/cris/cris.md ("smulsi3_highpart", "umulsi3_highpart")
("mulsidi3", "umulsidi3"): Prefix output template with "%!".
("umulhisi3", "umulqihi3", "mulsi3", "mulqihi3", "mulhisi3"):
Ditto. Make attribute "slottable" dependent on TARGET_MUL_BUG.
* config/cris/mulsi3.asm (__Mul) [__CRIS_arch_version >= 10]: Make
sure mulu.d is not last on cache-line.
* config/cris/cris.h (ASM_SPEC): Translate -mno-mul-bug-workaround
into -no-mul-bug-abort depending on HAVE_AS_MUL_BUG_ABORT_OPTION.
(TARGET_MASK_MUL_BUG, TARGET_MUL_BUG): New macros.
(TARGET_SWITCHES): New options -mmul-bug-workaround and
-mno-mul-bug-workaround.
(TARGET_DEFAULT): Include TARGET_MASK_MUL_BUG.
(PRINT_OPERAND_PUNCT_VALID_P): Include '!'.
* config/cris/cris.c (cris_operand_extend_operator): Clarify
relation to MULT in head comment.
(cris_op_str): Abort for MULT.
(cris_print_operand) <case '!'>: New case.
Index: invoke.texi
===================================================================
RCS file: /cvs/gcc/gcc/gcc/doc/invoke.texi,v
retrieving revision 1.422
diff -p -c -r1.422 invoke.texi
*** invoke.texi 4 Mar 2004 00:18:53 -0000 1.422
--- invoke.texi 7 Mar 2004 22:24:39 -0000
*************** in the following sections.
*** 609,615 ****
-metrax4 -metrax100 -mpdebug -mcc-init -mno-side-effects @gol
-mstack-align -mdata-align -mconst-align @gol
-m32-bit -m16-bit -m8-bit -mno-prologue-epilogue -mno-gotplt @gol
! -melf -maout -melinux -mlinux -sim -sim2}
@emph{PDP-11 Options}
@gccoptlist{-mfpu -msoft-float -mac0 -mno-ac0 -m40 -m45 -m10 @gol
--- 609,616 ----
-metrax4 -metrax100 -mpdebug -mcc-init -mno-side-effects @gol
-mstack-align -mdata-align -mconst-align @gol
-m32-bit -m16-bit -m8-bit -mno-prologue-epilogue -mno-gotplt @gol
! -melf -maout -melinux -mlinux -sim -sim2 @gol
! -mmul-bug-workaround -mno-mul-bug-workaround}
@emph{PDP-11 Options}
@gccoptlist{-mfpu -msoft-float -mac0 -mno-ac0 -m40 -m45 -m10 @gol
*************** program should be set to @var{n} bytes.
*** 10145,10150 ****
--- 10146,10158 ----
@opindex metrax100
The options @option{-metrax4} and @option{-metrax100} are synonyms for
@option{-march=v3} and @option{-march=v8} respectively.
+
+ @item -mmul-bug-workaround
+ @itemx -mno-mul-bug-workaround
+ @opindex mmul-bug-workaround
+ @opindex mno-mul-bug-workaround
+ Work around a bug in the @code{muls} and @code{mulu} instructions for CPU
+ models where it applies. This option is active by default.
@item -mpdebug
@opindex mpdebug
Index: configure.ac
===================================================================
RCS file: /cvs/gcc/gcc/gcc/configure.ac,v
retrieving revision 2.6.2.10
diff -p -c -r2.6.2.10 configure.ac
*** configure.ac 25 Feb 2004 21:54:58 -0000 2.6.2.10
--- configure.ac 7 Mar 2004 22:26:15 -0000
*************** case "$target" in
*** 2333,2338 ****
--- 2333,2346 ----
[Define if your assembler supports explicit relocations.])])
;;
+ cris-*-*)
+ gcc_GAS_CHECK_FEATURE([-no-mul-bug-abort option],
+ gcc_cv_as_cris_no_mul_bug,[2,15,91],
+ [-no-mul-bug-abort], [.text],,
+ [AC_DEFINE(HAVE_AS_NO_MUL_BUG_ABORT_OPTION, 1,
+ [Define if your assembler supports the -no-mul-bug-abort option.])])
+ ;;
+
sparc*-*-*)
gcc_GAS_CHECK_FEATURE([.register], gcc_cv_as_sparc_register_op,,,
[.register %g2, #scratch],,
Index: cris.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/cris/cris.c,v
retrieving revision 1.46.10.1
diff -p -c -r1.46.10.1 cris.c
*** cris.c 18 Jan 2004 22:39:57 -0000 1.46.10.1
--- cris.c 7 Mar 2004 22:29:22 -0000
*************** cris_commutative_orth_op (rtx x, enum ma
*** 318,324 ****
|| code == IOR || code == AND || code == UMIN));
}
! /* Check if MODE is same as mode for X, and X is PLUS or MINUS or UMIN. */
int
cris_operand_extend_operator (rtx x, enum machine_mode mode)
--- 318,327 ----
|| code == IOR || code == AND || code == UMIN));
}
! /* Check if MODE is same as mode for X, and X is PLUS or MINUS or UMIN.
! By the name, you might think we should include MULT. We don't because
! it doesn't accept the same addressing modes as the others (ony
! registers) and there's also the problem of handling TARGET_MUL_BUG. */
int
cris_operand_extend_operator (rtx x, enum machine_mode mode)
*************** cris_op_str (rtx x)
*** 485,491 ****
break;
case MULT:
! return "mul";
break;
case DIV:
--- 488,498 ----
break;
case MULT:
! /* This function is for retrieving a part of an instruction name for
! an operator, for immediate output. If that ever happens for
! MULT, we need to apply TARGET_MUL_BUG in the caller. Make sure
! we notice. */
! abort ();
break;
case DIV:
*************** cris_print_operand (FILE *file, rtx x, i
*** 1378,1383 ****
--- 1385,1407 ----
fputs ("\n\tnop", file);
return;
+ case '!':
+ /* Output directive for alignment padded with "nop" insns.
+ Optimizing for size, it's plain 4-byte alignment, otherwise we
+ align the section to a cache-line (32 bytes) and skip at max 2
+ bytes, i.e. we skip if it's the last insn on a cache-line. The
+ latter is faster by a small amount (for two test-programs 99.6%
+ and 99.9%) and larger by a small amount (ditto 100.1% and
+ 100.2%). This is supposed to be the simplest yet performance-
+ wise least intrusive way to make sure the immediately following
+ (supposed) muls/mulu insn isn't located at the end of a
+ cache-line. */
+ if (TARGET_MUL_BUG)
+ fputs (optimize_size
+ ? ".p2alignw 2,0x050f\n\t"
+ : ".p2alignw 5,0x050f,2\n\t", file);
+ return;
+
case 'H':
/* Print high (most significant) part of something. */
switch (GET_CODE (operand))
Index: cris.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/cris/cris.h,v
retrieving revision 1.60
diff -p -c -r1.60 cris.h
*** cris.h 13 Dec 2003 04:44:04 -0000 1.60
--- cris.h 7 Mar 2004 22:29:26 -0000
*************** extern const char *cris_elinux_stacksize
*** 170,178 ****
--- 170,186 ----
%{!melinux:%{!maout|melf:%{!fno-vtable-gc:-fvtable-gc}}}}}". */
#define CC1PLUS_SPEC ""
+ #ifdef HAVE_AS_MUL_BUG_ABORT_OPTION
+ #define MAYBE_AS_NO_MUL_BUG_ABORT \
+ "%{mno-mul-bug-workaround:-no-mul-bug-abort} "
+ #else
+ #define MAYBE_AS_NO_MUL_BUG_ABORT
+ #endif
+
/* Override previous definitions (linux.h). */
#undef ASM_SPEC
#define ASM_SPEC \
+ MAYBE_AS_NO_MUL_BUG_ABORT \
"%{v:-v}\
%(asm_subtarget)"
*************** extern int target_flags;
*** 325,332 ****
--- 333,366 ----
#define TARGET_MASK_AVOID_GOTPLT 8192
#define TARGET_AVOID_GOTPLT (target_flags & TARGET_MASK_AVOID_GOTPLT)
+ /* Whether or not to work around multiplication instruction hardware bug
+ when generating code for models where it may be present. From the
+ trouble report for Etrax 100 LX: "A multiply operation may cause
+ incorrect cache behaviour under some specific circumstances. The
+ problem can occur if the instruction following the multiply instruction
+ causes a cache miss, and multiply operand 1 (source operand) bits
+ [31:27] matches the logical mapping of the mode register address
+ (0xb0....), and bits [9:2] of operand 1 matches the TLB register
+ address (0x258-0x25f). There is such a mapping in kernel mode or when
+ the MMU is off. Normally there is no such mapping in user mode, and
+ the problem will therefore probably not occur in Linux user mode
+ programs."
+
+ We have no sure-fire way to know from within GCC that we're compiling a
+ user program. For example, -fpic/PIC is used in libgcc which is linked
+ into the kernel. However, the workaround option -mno-mul-bug can be
+ safely used per-package when compiling programs. The same goes for
+ general user-only libraries such as glibc, since there's no user-space
+ driver-like program that gets a mapping of I/O registers (all on the
+ same page, including the TLB registers). */
+ #define TARGET_MASK_MUL_BUG 16384
+ #define TARGET_MUL_BUG (target_flags & TARGET_MASK_MUL_BUG)
+
#define TARGET_SWITCHES \
{ \
+ {"mul-bug-workaround", TARGET_MASK_MUL_BUG, \
+ N_("Work around bug in multiplication instruction")}, \
+ {"no-mul-bug-workaround", -TARGET_MASK_MUL_BUG, ""}, \
/* No "no-etrax" as it does not really imply any model. \
On the other hand, "etrax" implies the common (and large) \
subset matching all models. */ \
*************** extern int target_flags;
*** 404,410 ****
# define TARGET_DEFAULT \
(TARGET_MASK_SIDE_EFFECT_PREFIXES + TARGET_MASK_STACK_ALIGN \
+ TARGET_MASK_CONST_ALIGN + TARGET_MASK_DATA_ALIGN \
! + TARGET_MASK_PROLOGUE_EPILOGUE)
#endif
/* For the cris-*-elf subtarget. */
--- 438,444 ----
# define TARGET_DEFAULT \
(TARGET_MASK_SIDE_EFFECT_PREFIXES + TARGET_MASK_STACK_ALIGN \
+ TARGET_MASK_CONST_ALIGN + TARGET_MASK_DATA_ALIGN \
! + TARGET_MASK_PROLOGUE_EPILOGUE + TARGET_MASK_MUL_BUG)
#endif
/* For the cris-*-elf subtarget. */
*************** call_ ## FUNC (void) \
*** 1497,1503 ****
cris_print_operand (FILE, X, CODE)
/* For delay-slot handling. */
! #define PRINT_OPERAND_PUNCT_VALID_P(CODE) (CODE == '#')
#define PRINT_OPERAND_ADDRESS(FILE, ADDR) \
cris_print_operand_address (FILE, ADDR)
--- 1531,1538 ----
cris_print_operand (FILE, X, CODE)
/* For delay-slot handling. */
! #define PRINT_OPERAND_PUNCT_VALID_P(CODE) \
! ((CODE) == '#' || (CODE) == '!')
#define PRINT_OPERAND_ADDRESS(FILE, ADDR) \
cris_print_operand_address (FILE, ADDR)
Index: cris.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/cris/cris.md,v
retrieving revision 1.11.4.1
diff -p -c -r1.11.4.1 cris.md
*** cris.md 22 Feb 2004 11:13:04 -0000 1.11.4.1
--- cris.md 7 Mar 2004 22:29:26 -0000
***************
*** 2468,2475 ****
(zero_extend:SI (match_operand:HI 1 "register_operand" "0"))
(zero_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
"TARGET_HAS_MUL_INSNS"
! "mulu.w %2,%0"
! [(set_attr "slottable" "yes")
;; Just N unusable here, but let's be safe.
(set_attr "cc" "clobber")])
--- 2468,2478 ----
(zero_extend:SI (match_operand:HI 1 "register_operand" "0"))
(zero_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
"TARGET_HAS_MUL_INSNS"
! "%!mulu.w %2,%0"
! [(set (attr "slottable")
! (if_then_else (ne (symbol_ref "TARGET_MUL_BUG") (const_int 0))
! (const_string "no")
! (const_string "yes")))
;; Just N unusable here, but let's be safe.
(set_attr "cc" "clobber")])
***************
*** 2479,2486 ****
(zero_extend:HI (match_operand:QI 1 "register_operand" "0"))
(zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
"TARGET_HAS_MUL_INSNS"
! "mulu.b %2,%0"
! [(set_attr "slottable" "yes")
;; Not exactly sure, but let's be safe.
(set_attr "cc" "clobber")])
--- 2482,2492 ----
(zero_extend:HI (match_operand:QI 1 "register_operand" "0"))
(zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
"TARGET_HAS_MUL_INSNS"
! "%!mulu.b %2,%0"
! [(set (attr "slottable")
! (if_then_else (ne (symbol_ref "TARGET_MUL_BUG") (const_int 0))
! (const_string "no")
! (const_string "yes")))
;; Not exactly sure, but let's be safe.
(set_attr "cc" "clobber")])
***************
*** 2495,2502 ****
(mult:SI (match_operand:SI 1 "register_operand" "0")
(match_operand:SI 2 "register_operand" "r")))]
"TARGET_HAS_MUL_INSNS"
! "muls.d %2,%0"
! [(set_attr "slottable" "yes")
;; Just N unusable here, but let's be safe.
(set_attr "cc" "clobber")])
--- 2501,2511 ----
(mult:SI (match_operand:SI 1 "register_operand" "0")
(match_operand:SI 2 "register_operand" "r")))]
"TARGET_HAS_MUL_INSNS"
! "%!muls.d %2,%0"
! [(set (attr "slottable")
! (if_then_else (ne (symbol_ref "TARGET_MUL_BUG") (const_int 0))
! (const_string "no")
! (const_string "yes")))
;; Just N unusable here, but let's be safe.
(set_attr "cc" "clobber")])
***************
*** 2510,2517 ****
(sign_extend:HI (match_operand:QI 1 "register_operand" "0"))
(sign_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
"TARGET_HAS_MUL_INSNS"
! "muls.b %2,%0"
! [(set_attr "slottable" "yes")
(set_attr "cc" "clobber")])
(define_insn "mulhisi3"
--- 2519,2529 ----
(sign_extend:HI (match_operand:QI 1 "register_operand" "0"))
(sign_extend:HI (match_operand:QI 2 "register_operand" "r"))))]
"TARGET_HAS_MUL_INSNS"
! "%!muls.b %2,%0"
! [(set (attr "slottable")
! (if_then_else (ne (symbol_ref "TARGET_MUL_BUG") (const_int 0))
! (const_string "no")
! (const_string "yes")))
(set_attr "cc" "clobber")])
(define_insn "mulhisi3"
***************
*** 2520,2527 ****
(sign_extend:SI (match_operand:HI 1 "register_operand" "0"))
(sign_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
"TARGET_HAS_MUL_INSNS"
! "muls.w %2,%0"
! [(set_attr "slottable" "yes")
;; Just N unusable here, but let's be safe.
(set_attr "cc" "clobber")])
--- 2532,2542 ----
(sign_extend:SI (match_operand:HI 1 "register_operand" "0"))
(sign_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
"TARGET_HAS_MUL_INSNS"
! "%!muls.w %2,%0"
! [(set (attr "slottable")
! (if_then_else (ne (symbol_ref "TARGET_MUL_BUG") (const_int 0))
! (const_string "no")
! (const_string "yes")))
;; Just N unusable here, but let's be safe.
(set_attr "cc" "clobber")])
***************
*** 2537,2543 ****
(sign_extend:DI (match_operand:SI 1 "register_operand" "0"))
(sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
"TARGET_HAS_MUL_INSNS"
! "muls.d %2,%M0\;move $mof,%H0")
(define_insn "umulsidi3"
[(set (match_operand:DI 0 "register_operand" "=r")
--- 2552,2558 ----
(sign_extend:DI (match_operand:SI 1 "register_operand" "0"))
(sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
"TARGET_HAS_MUL_INSNS"
! "%!muls.d %2,%M0\;move $mof,%H0")
(define_insn "umulsidi3"
[(set (match_operand:DI 0 "register_operand" "=r")
***************
*** 2545,2551 ****
(zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
(zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
"TARGET_HAS_MUL_INSNS"
! "mulu.d %2,%M0\;move $mof,%H0")
;; This pattern would probably not be needed if we add "mof" in its own
;; register class (and open a can of worms about /not/ pairing it with a
--- 2560,2566 ----
(zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
(zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
"TARGET_HAS_MUL_INSNS"
! "%!mulu.d %2,%M0\;move $mof,%H0")
;; This pattern would probably not be needed if we add "mof" in its own
;; register class (and open a can of worms about /not/ pairing it with a
***************
*** 2564,2570 ****
(const_int 32))))
(clobber (match_scratch:SI 3 "=X,1,1"))]
"TARGET_HAS_MUL_INSNS"
! "muls.d %2,%1\;move $mof,%0"
[(set_attr "cc" "clobber")])
(define_insn "umulsi3_highpart"
--- 2579,2585 ----
(const_int 32))))
(clobber (match_scratch:SI 3 "=X,1,1"))]
"TARGET_HAS_MUL_INSNS"
! "%!muls.d %2,%1\;move $mof,%0"
[(set_attr "cc" "clobber")])
(define_insn "umulsi3_highpart"
***************
*** 2577,2583 ****
(const_int 32))))
(clobber (match_scratch:SI 3 "=X,1,1"))]
"TARGET_HAS_MUL_INSNS"
! "mulu.d %2,%1\;move $mof,%0"
[(set_attr "cc" "clobber")])
;; Divide and modulus instructions. CRIS only has a step instruction.
--- 2592,2598 ----
(const_int 32))))
(clobber (match_scratch:SI 3 "=X,1,1"))]
"TARGET_HAS_MUL_INSNS"
! "%!mulu.d %2,%1\;move $mof,%0"
[(set_attr "cc" "clobber")])
;; Divide and modulus instructions. CRIS only has a step instruction.
Index: mulsi3.asm
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/cris/mulsi3.asm,v
retrieving revision 1.1
diff -p -c -r1.1 mulsi3.asm
*** mulsi3.asm 11 Oct 2001 17:02:36 -0000 1.1
--- mulsi3.asm 7 Mar 2004 22:29:27 -0000
***************
*** 82,89 ****
.type ___Mul,@function
___Mul:
#if defined (__CRIS_arch_version) && __CRIS_arch_version >= 10
! ret
mulu.d $r11,$r10
#else
move.d $r10,$r12
move.d $r11,$r9
--- 82,94 ----
.type ___Mul,@function
___Mul:
#if defined (__CRIS_arch_version) && __CRIS_arch_version >= 10
! ;; Can't have the mulu.d last on a cache-line (in the delay-slot of the
! ;; "ret"), due to hardware bug. See documentation for -mmul-bug-workaround.
! ;; Not worthwhile to conditionalize here.
! .p2alignw 2,0x050f
mulu.d $r11,$r10
+ ret
+ nop
#else
move.d $r10,$r12
move.d $r11,$r9
brgds, H-P
More information about the Gcc-patches
mailing list