OSDN Git Service

* config/avr/avr.c (print_operand): Check that addr is a SYMBOL_REF
authormarekm <marekm@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 10 May 2002 12:22:36 +0000 (12:22 +0000)
committermarekm <marekm@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 10 May 2002 12:22:36 +0000 (12:22 +0000)
before using SYMBOL_REF_FLAG (addr).

* config/avr/avr-protos.h (avr_io_address_p): Declare.
* config/avr/avr.c (io_address_p): Rename to avr_io_address_p.
Make non-static.  Update all callers.
* config/avr/avr.md (*cbi, *sbi, *sbix_branch, *sbix_branch_bit7):
New insns to clear/set/test a single bit in I/O address space.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@53359 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/avr/avr-protos.h
gcc/config/avr/avr.c
gcc/config/avr/avr.md

index 94b8790..8d1122a 100644 (file)
@@ -1,3 +1,14 @@
+2002-05-10  Marek Michalkiewicz  <marekm@amelek.gda.pl>
+
+       * config/avr/avr.c (print_operand): Check that addr is a SYMBOL_REF
+       before using SYMBOL_REF_FLAG (addr).
+
+       * config/avr/avr-protos.h (avr_io_address_p): Declare.
+       * config/avr/avr.c (io_address_p): Rename to avr_io_address_p.
+       Make non-static.  Update all callers.
+       * config/avr/avr.md (*cbi, *sbi, *sbix_branch, *sbix_branch_bit7):
+       New insns to clear/set/test a single bit in I/O address space.
+
 2002-05-09  Kaveh R. Ghazi  <ghazi@caip.rutgers.edu>
 
        * rtl.h (ENABLE_RTL_FLAG_CHECKING): Also check for gcc >= 2.7.
index 966a0cb..fe69e63 100644 (file)
@@ -141,6 +141,7 @@ extern int    compare_eq_p           PARAMS ((rtx insn));
 extern void   out_shift_with_cnt     PARAMS ((const char *template, rtx insn,
                                              rtx operands[], int *len,
                                              int t_len));
+extern int    avr_io_address_p      PARAMS ((rtx x, int size));
 extern int    const_int_pow2_p       PARAMS ((rtx x));
 extern int    avr_peep2_scratch_safe PARAMS ((rtx reg_rtx));
 #endif /* RTX_CODE */
index 30ea833..4027662 100644 (file)
@@ -56,7 +56,6 @@ static int    out_set_stack_ptr    PARAMS ((FILE *, int, int));
 static RTX_CODE compare_condition  PARAMS ((rtx insn));
 static int    compare_sign_p       PARAMS ((rtx insn));
 static int    reg_was_0            PARAMS ((rtx insn, rtx op));
-static int    io_address_p         PARAMS ((rtx x, int size));
 void          debug_hard_reg_set   PARAMS ((HARD_REG_SET set));
 static tree   avr_handle_progmem_attribute PARAMS ((tree *, tree, tree, int, bool *));
 static tree   avr_handle_fndecl_attribute PARAMS ((tree *, tree, tree, int, bool *));
@@ -1001,7 +1000,8 @@ print_operand_address (file, addr)
 
     default:
       if (CONSTANT_ADDRESS_P (addr)
-         && (SYMBOL_REF_FLAG (addr) || GET_CODE (addr) == LABEL_REF))
+         && ((GET_CODE (addr) == SYMBOL_REF && SYMBOL_REF_FLAG (addr))
+             || GET_CODE (addr) == LABEL_REF))
        {
          fprintf (file, "pm(");
          output_addr_const (file,addr);
@@ -1802,7 +1802,7 @@ out_movqi_r_mr (insn, op, l)
   
   if (CONSTANT_ADDRESS_P (x))
     {
-      if (io_address_p (x, 1))
+      if (avr_io_address_p (x, 1))
        {
          *l = 1;
          return AS2 (in,%0,%1-0x20);
@@ -1971,7 +1971,7 @@ out_movhi_r_mr (insn, op, l)
     }
   else if (CONSTANT_ADDRESS_P (base))
     {
-      if (io_address_p (base, 2))
+      if (avr_io_address_p (base, 2))
        {
          *l = 2;
          return (AS2 (in,%A0,%A1-0x20) CR_TAB
@@ -2514,7 +2514,7 @@ out_movqi_mr_r (insn, op, l)
   
   if (CONSTANT_ADDRESS_P (x))
     {
-      if (io_address_p (x, 1))
+      if (avr_io_address_p (x, 1))
        {
          *l = 1;
          return AS2 (out,%0-0x20,%1);
@@ -2592,7 +2592,7 @@ out_movhi_mr_r (insn, op, l)
     l = &tmp;
   if (CONSTANT_ADDRESS_P (base))
     {
-      if (io_address_p (base, 2))
+      if (avr_io_address_p (base, 2))
        {
          *l = 2;
          return (AS2 (out,%B0-0x20,%B1) CR_TAB
@@ -4927,7 +4927,7 @@ avr_address_cost (x)
     return 18;
   if (CONSTANT_ADDRESS_P (x))
     {
-      if (io_address_p (x, 1))
+      if (avr_io_address_p (x, 1))
        return 2;
       return 4;
     }
@@ -5246,10 +5246,11 @@ reg_was_0 (insn, op)
 }
 
 /* Returns 1 if X is a valid address for an I/O register of size SIZE
-   (1 or 2).  Used for lds/sts -> in/out optimization.  */
+   (1 or 2).  Used for lds/sts -> in/out optimization.  Add 0x20 to SIZE
+   to check for the lower half of I/O space (for cbi/sbi/sbic/sbis).  */
 
-static int
-io_address_p (x, size)
+int
+avr_io_address_p (x, size)
      rtx x;
      int size;
 {
index 762288f..da4c571 100644 (file)
   [(set_attr "length" "1")
    (set_attr "cc" "compare")])
 
+;; Clear/set/test a single bit in I/O address space.
+
+(define_insn "*cbi"
+  [(set (mem:QI (match_operand 0 "const_int_operand" "n"))
+       (and:QI (mem:QI (match_dup 0))
+               (match_operand 1 "const_int_operand" "n")))]
+  "avr_io_address_p (operands[0], 1 + 0x20)
+   && exact_log2 (~INTVAL (operands[1]) & 0xff) >= 0"
+{
+  operands[2] = GEN_INT (exact_log2 (~INTVAL (operands[1]) & 0xff));
+  return AS2 (cbi,%0-0x20,%2);
+}
+  [(set_attr "length" "1")
+   (set_attr "cc" "none")])
+
+(define_insn "*sbi"
+  [(set (mem:QI (match_operand 0 "const_int_operand" "n"))
+       (ior:QI (mem:QI (match_dup 0))
+               (match_operand 1 "const_int_operand" "n")))]
+  "avr_io_address_p (operands[0], 1 + 0x20)
+   && exact_log2 (INTVAL (operands[1]) & 0xff) >= 0"
+{
+  operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1]) & 0xff));
+  return AS2 (sbi,%0-0x20,%2);
+}
+  [(set_attr "length" "1")
+   (set_attr "cc" "none")])
+
+(define_insn "*sbix_branch"
+  [(set (pc)
+       (if_then_else
+        (match_operator 0 "comparison_operator"
+                        [(zero_extract
+                          (mem:QI (match_operand 1 "const_int_operand" "n"))
+                          (const_int 1)
+                          (match_operand 2 "const_int_operand" "n"))
+                         (const_int 0)])
+        (label_ref (match_operand 3 "" ""))
+        (pc)))]
+  "(GET_CODE (operands[0]) == EQ || GET_CODE (operands[0]) == NE)
+   && avr_io_address_p (operands[1], 1 + 0x20)"
+{
+  enum rtx_code comp = GET_CODE (operands[0]);
+  int reverse = (get_attr_length (insn) == 4);
+
+  if (reverse)
+    comp = reverse_condition (comp);
+  if (comp == EQ)
+    output_asm_insn (AS2 (sbis,%1-0x20,%2), operands);
+  else
+    output_asm_insn (AS2 (sbic,%1-0x20,%2), operands);
+  if (!reverse)
+    return AS1 (rjmp,%3);
+  return (AS1 (rjmp,_PC_+4) CR_TAB
+         AS1 (jmp,%3));
+}
+  [(set (attr "length")
+       (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
+                          (le (minus (pc) (match_dup 3)) (const_int 2046)))
+                     (const_int 2)
+                     (if_then_else (eq_attr "mcu_mega" "no")
+                                   (const_int 2)
+                                   (const_int 4))))
+   (set_attr "cc" "clobber")])
+
+;; Tests of bit 7 are pessimized to sign tests, so we need this too...
+(define_insn "*sbix_branch_bit7"
+  [(set (pc)
+       (if_then_else
+        (match_operator 0 "comparison_operator"
+                        [(mem:QI (match_operand 1 "const_int_operand" "n"))
+                         (const_int 0)])
+        (label_ref (match_operand 2 "" ""))
+        (pc)))]
+  "(GET_CODE (operands[0]) == GE || GET_CODE (operands[0]) == LT)
+   && avr_io_address_p (operands[1], 1 + 0x20)"
+{
+  enum rtx_code comp = GET_CODE (operands[0]);
+  int reverse = (get_attr_length (insn) == 4);
+
+  if (reverse)
+    comp = reverse_condition (comp);
+  if (comp == GE)
+    output_asm_insn (AS2 (sbis,%1-0x20,7), operands);
+  else
+    output_asm_insn (AS2 (sbic,%1-0x20,7), operands);
+  if (!reverse)
+    return AS1 (rjmp,%2);
+  return (AS1 (rjmp,_PC_+4) CR_TAB
+         AS1 (jmp,%2));
+}
+  [(set (attr "length")
+       (if_then_else (and (ge (minus (pc) (match_dup 2)) (const_int -2046))
+                          (le (minus (pc) (match_dup 2)) (const_int 2046)))
+                     (const_int 2)
+                     (if_then_else (eq_attr "mcu_mega" "no")
+                                   (const_int 2)
+                                   (const_int 4))))
+   (set_attr "cc" "clobber")])
 
 ;; ************************* Peepholes ********************************