This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[m68k 13/13] restrict bitfield operations with dynamic parameter


Hi,

When combine creates a bitfield instruction it assumes simple shift
operations, but it doesn't work quite that way on m68k. If the bitfield
crosses the register boundary it wraps around, thus it actually is a
rotate operation.

This example demonstrates where it goes wrong (reduced from emacs):

#define XINT(v) (((int)(v) << 4) >> 4)
#define XUINT(v) (((unsigned)(v) << 4) >> 4)

int f(int v, int s)
{
	return (XUINT(v) >> -XINT(s)) & 0x0fffffff;
}

gcc takes the shift and the mask and generates a bitfield op, but the
real bitfield instruction wraps around at the register end and doesn't
produce the expected result.

I guess it would be quite some work to teach combine about this and I
don't know how these behave on other ports, so the simple solution
below just disables dynamic offsets and widths for register arguments
and while I'm at it I also cleaned up the predicates here as well.



2007-01-30  Roman Zippel <zippel@linux-m68k.org>

	* config/m68k/m68k.md (extv,extzv,insv): disable dynamic
	parameter for register bitfield operations, general predicates
	cleanup

---

 gcc/config/m68k/m68k.md |   62 ++++++++++++++++++++++++------------------------
 1 file changed, 31 insertions(+), 31 deletions(-)

Index: gcc-4.1/gcc/config/m68k/m68k.md
===================================================================
--- gcc-4.1.orig/gcc/config/m68k/m68k.md
+++ gcc-4.1/gcc/config/m68k/m68k.md
@@ -4991,34 +4991,34 @@
 ;; so that its address is reloaded.
 
 (define_expand "extv"
-  [(set (match_operand:SI 0 "nonimmediate_operand" "")
+  [(set (match_operand:SI 0 "register_operand" "")
 	(sign_extract:SI (match_operand:SI 1 "general_operand" "")
-			 (match_operand:SI 2 "general_operand" "")
-			 (match_operand:SI 3 "general_operand" "")))]
+			 (match_operand:SI 2 "const_int_operand" "")
+			 (match_operand:SI 3 "const_int_operand" "")))]
   "TARGET_68020 && TARGET_BITFIELD"
   "")
 
 (define_insn ""
-  [(set (match_operand:SI 0 "nonimmediate_operand" "=d")
+  [(set (match_operand:SI 0 "register_operand" "=d")
 	(sign_extract:SI (match_operand:QI 1 "memory_operand" "o")
-			 (match_operand:SI 2 "general_operand" "dn")
-			 (match_operand:SI 3 "general_operand" "dn")))]
+			 (match_operand:SI 2 "nonmemory_operand" "dn")
+			 (match_operand:SI 3 "nonmemory_operand" "dn")))]
   "TARGET_68020 && TARGET_BITFIELD"
   "bfexts %1{%b3:%b2},%0")
 
 (define_expand "extzv"
-  [(set (match_operand:SI 0 "nonimmediate_operand" "")
+  [(set (match_operand:SI 0 "register_operand" "")
 	(zero_extract:SI (match_operand:SI 1 "general_operand" "")
-			 (match_operand:SI 2 "general_operand" "")
-			 (match_operand:SI 3 "general_operand" "")))]
+			 (match_operand:SI 2 "const_int_operand" "")
+			 (match_operand:SI 3 "const_int_operand" "")))]
   "TARGET_68020 && TARGET_BITFIELD"
   "")
 
 (define_insn ""
-  [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d")
-	(zero_extract:SI (match_operand:QI 1 "memory_operand" "o,d")
-			 (match_operand:SI 2 "general_operand" "dn,dn")
-			 (match_operand:SI 3 "general_operand" "dn,dn")))]
+  [(set (match_operand:SI 0 "register_operand" "=d")
+	(zero_extract:SI (match_operand:QI 1 "memory_operand" "o")
+			 (match_operand:SI 2 "nonmemory_operand" "dn")
+			 (match_operand:SI 3 "nonmemory_operand" "dn")))]
   "TARGET_68020 && TARGET_BITFIELD"
 {
   if (GET_CODE (operands[2]) == CONST_INT)
@@ -5035,8 +5035,8 @@
 
 (define_insn ""
   [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "+o")
-			 (match_operand:SI 1 "general_operand" "dn")
-			 (match_operand:SI 2 "general_operand" "dn"))
+			 (match_operand:SI 1 "nonmemory_operand" "dn")
+			 (match_operand:SI 2 "nonmemory_operand" "dn"))
         (xor:SI (zero_extract:SI (match_dup 0) (match_dup 1) (match_dup 2))
 		(match_operand 3 "const_int_operand" "n")))]
   "TARGET_68020 && TARGET_BITFIELD
@@ -5050,8 +5050,8 @@
 
 (define_insn ""
   [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "+o")
-			 (match_operand:SI 1 "general_operand" "dn")
-			 (match_operand:SI 2 "general_operand" "dn"))
+			 (match_operand:SI 1 "nonmemory_operand" "dn")
+			 (match_operand:SI 2 "nonmemory_operand" "dn"))
 	(const_int 0))]
   "TARGET_68020 && TARGET_BITFIELD"
 {
@@ -5072,16 +5072,16 @@
 
 (define_expand "insv"
   [(set (zero_extract:SI (match_operand:SI 0 "nonimmediate_operand" "")
-			 (match_operand:SI 1 "general_operand" "")
-			 (match_operand:SI 2 "general_operand" ""))
+			 (match_operand:SI 1 "const_int_operand" "")
+			 (match_operand:SI 2 "const_int_operand" ""))
 	(match_operand:SI 3 "register_operand" ""))]
   "TARGET_68020 && TARGET_BITFIELD"
   "")
 
 (define_insn ""
   [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "+o")
-			 (match_operand:SI 1 "general_operand" "dn")
-			 (match_operand:SI 2 "general_operand" "dn"))
+			 (match_operand:SI 1 "nonmemory_operand" "dn")
+			 (match_operand:SI 2 "nonmemory_operand" "dn"))
 	(match_operand:SI 3 "register_operand" "d"))]
   "TARGET_68020 && TARGET_BITFIELD"
   "bfins %3,%0{%b2:%b1}")
@@ -5092,16 +5092,16 @@
 (define_insn ""
   [(set (match_operand:SI 0 "nonimmediate_operand" "=d")
 	(sign_extract:SI (match_operand:SI 1 "register_operand" "d")
-			 (match_operand:SI 2 "general_operand" "dn")
-			 (match_operand:SI 3 "general_operand" "dn")))]
+			 (match_operand:SI 2 "const_int_operand" "n")
+			 (match_operand:SI 3 "const_int_operand" "n")))]
   "TARGET_68020 && TARGET_BITFIELD"
   "bfexts %1{%b3:%b2},%0")
 
 (define_insn ""
   [(set (match_operand:SI 0 "nonimmediate_operand" "=d")
 	(zero_extract:SI (match_operand:SI 1 "register_operand" "d")
-			 (match_operand:SI 2 "general_operand" "dn")
-			 (match_operand:SI 3 "general_operand" "dn")))]
+			 (match_operand:SI 2 "const_int_operand" "n")
+			 (match_operand:SI 3 "const_int_operand" "n")))]
   "TARGET_68020 && TARGET_BITFIELD"
 {
   if (GET_CODE (operands[2]) == CONST_INT)
@@ -5118,8 +5118,8 @@
 
 (define_insn ""
   [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+d")
-			 (match_operand:SI 1 "general_operand" "dn")
-			 (match_operand:SI 2 "general_operand" "dn"))
+			 (match_operand:SI 1 "const_int_operand" "n")
+			 (match_operand:SI 2 "const_int_operand" "n"))
 	(const_int 0))]
   "TARGET_68020 && TARGET_BITFIELD"
 {
@@ -5129,8 +5129,8 @@
 
 (define_insn ""
   [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+d")
-			 (match_operand:SI 1 "general_operand" "dn")
-			 (match_operand:SI 2 "general_operand" "dn"))
+			 (match_operand:SI 1 "const_int_operand" "n")
+			 (match_operand:SI 2 "const_int_operand" "n"))
 	(const_int -1))]
   "TARGET_68020 && TARGET_BITFIELD"
 {
@@ -5140,8 +5140,8 @@
 
 (define_insn ""
   [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+d")
-			 (match_operand:SI 1 "general_operand" "dn")
-			 (match_operand:SI 2 "general_operand" "dn"))
+			 (match_operand:SI 1 "const_int_operand" "n")
+			 (match_operand:SI 2 "const_int_operand" "n"))
 	(match_operand:SI 3 "register_operand" "d"))]
   "TARGET_68020 && TARGET_BITFIELD"
 {

--


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]