avr.h (ASSEMBLER_DIALECT): Remove.
authorGeorg-Johann Lay <avr@gjlay.de>
Mon, 17 Oct 2011 17:53:07 +0000 (17:53 +0000)
committerGeorg-Johann Lay <gjl@gcc.gnu.org>
Mon, 17 Oct 2011 17:53:07 +0000 (17:53 +0000)
* config/avr/avr.h (ASSEMBLER_DIALECT): Remove.
* config/avr/avr.md (mcu_have_movw, mcu_mega): Remove attributes.
(adjust_len): Add alternative "call".
(isa, enabled): New insn attributes.
(length): Use match_test with AVR_HAVE_JMP_CALL instead of
mcu_mega attribute.
(*sbrx_branch<mode>): Ditto.
(*sbrx_and_branch<mode>): Ditto.
(*sbix_branch): Ditto.
(*sbix_branch_bit7): Ditto.
(*sbix_branch_tmp): Ditto.
(*sbix_branch_tmp_bit7): Ditto.
(jump): Ditto.
(negsi2): Use attribute "isa" instead of assembler dialect.
(extendhisi2): Ditto.
(call_insn, call_value_insn): Set adjust_len attribute.
(indirect_jump): Indent to coding rules.
(call_prologue_saves): Use isa attribute instead of mcu_mega.
(epilogue_restores): Ditto.  Fix setting of SP as described in the
RTX pattern.
(*indirect_jump): Fusion of *jcindirect_jump, *njcindirect_jump
and *indirect_jump_avr6.
(*tablejump): Fusion of *tablejump_rjmp and *tablejump_lib.
(*jcindirect_jump, *njcindirect_jump, *indirect_jump_avr6): Remove.
(*tablejump_rjmp, *tablejump_lib): Remove.
* config/avr/avr.c (adjust_insn_length): Handle ADJUST_LEN_CALL.

From-SVN: r180104

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

index 1c0ddaaa598ddfe7a32c3aeb82356f0b31f3463b..ca205f60398b5be2aadc5e340ad703466e269feb 100644 (file)
@@ -1,3 +1,32 @@
+2011-10-17  Georg-Johann Lay  <avr@gjlay.de>
+
+       * config/avr/avr.h (ASSEMBLER_DIALECT): Remove.
+       * config/avr/avr.md (mcu_have_movw, mcu_mega): Remove attributes.
+       (adjust_len): Add alternative "call".
+       (isa, enabled): New insn attributes.
+       (length): Use match_test with AVR_HAVE_JMP_CALL instead of
+       mcu_mega attribute.
+       (*sbrx_branch<mode>): Ditto.
+       (*sbrx_and_branch<mode>): Ditto.
+       (*sbix_branch): Ditto.
+       (*sbix_branch_bit7): Ditto.
+       (*sbix_branch_tmp): Ditto.
+       (*sbix_branch_tmp_bit7): Ditto.
+       (jump): Ditto.
+       (negsi2): Use attribute "isa" instead of assembler dialect.
+       (extendhisi2): Ditto.
+       (call_insn, call_value_insn): Set adjust_len attribute.
+       (indirect_jump): Indent to coding rules.
+       (call_prologue_saves): Use isa attribute instead of mcu_mega.
+       (epilogue_restores): Ditto.  Fix setting of SP as described in the
+       RTX pattern.
+       (*indirect_jump): Fusion of *jcindirect_jump, *njcindirect_jump
+       and *indirect_jump_avr6.
+       (*tablejump): Fusion of *tablejump_rjmp and *tablejump_lib.
+       (*jcindirect_jump, *njcindirect_jump, *indirect_jump_avr6): Remove.
+       (*tablejump_rjmp, *tablejump_lib): Remove.
+       * config/avr/avr.c (adjust_insn_length): Handle ADJUST_LEN_CALL.
+
 2011-10-17  Paolo Carlini  <paolo.carlini@oracle.com>
 
        PR c++/50757
index 22db97dabadf25fd454d45670eb53f5f2c429452..c0ce6f9ace09c9311ed4420560803056e8717c29 100644 (file)
@@ -5331,6 +5331,8 @@ adjust_insn_length (rtx insn, int len)
     case ADJUST_LEN_ASHLHI: ashlhi3_out (insn, op, &len); break;
     case ADJUST_LEN_ASHLSI: ashlsi3_out (insn, op, &len); break;
       
+    case ADJUST_LEN_CALL: len = AVR_HAVE_JMP_CALL ? 2 : 1; break;
+
     default:
       gcc_unreachable();
     }
index 015f12b5fe51306eaabea890306b3eba61488014..1a5f20a0e13b6d177558e8e2c72dff5eff0e0bdc 100644 (file)
@@ -454,8 +454,6 @@ typedef struct avr_args {
 
 #define PRINT_OPERAND_ADDRESS(STREAM, X) print_operand_address(STREAM, X)
 
-#define ASSEMBLER_DIALECT AVR_HAVE_MOVW
-
 #define ASM_OUTPUT_REG_PUSH(STREAM, REGNO)     \
 {                                              \
   gcc_assert (REGNO < 32);                     \
index 1052378de652e751a5457697be9905bb1b086b07..aafdc554a10282d7b446320be181620d02c111de 100644 (file)
 (define_attr "type" "branch,branch1,arith,xcall"
   (const_string "arith"))
 
-(define_attr "mcu_have_movw" "yes,no"
-  (const (if_then_else (symbol_ref "AVR_HAVE_MOVW")
-                      (const_string "yes")
-                      (const_string "no"))))
-
-(define_attr "mcu_mega" "yes,no"
-  (const (if_then_else (symbol_ref "AVR_HAVE_JMP_CALL")
-                      (const_string "yes")
-                      (const_string "no"))))
-  
-
 ;; The size of instructions in bytes.
 ;; XXX may depend from "cc"
 
                                      (const_int 3)
                                      (const_int 4)))
         (eq_attr "type" "xcall")
-        (if_then_else (eq_attr "mcu_mega" "no")
+        (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
                       (const_int 1)
                       (const_int 2))]
         (const_int 2)))
 ;; Following insn attribute tells if and how the adjustment has to be
 ;; done:
 ;;     no     No adjustment needed; attribute "length" is fine.
-;;     yes    Analyse pattern in adjust_insn_length by hand.
 ;; Otherwise do special processing depending on the attribute.
 
 (define_attr "adjust_len"
-  "out_bitop, out_plus, addto_sp, tsthi, tstsi, compare,
+  "out_bitop, out_plus, addto_sp, tsthi, tstsi, compare, call,
    mov8, mov16, mov32, reload_in16, reload_in32,
    ashlqi, ashrqi, lshrqi,
    ashlhi, ashrhi, lshrhi,
    no"
   (const_string "no"))
 
+;; Flavours of instruction set architecture (ISA), used in enabled attribute
+
+;; mov:   ISA has no MOVW
+;; movw:  ISA has MOVW
+;; rjmp:  ISA has no CALL/JMP
+;; jmp:   ISA has CALL/JMP
+;; ijmp:  ISA has no EICALL/EIJMP
+;; eijmp: ISA has EICALL/EIJMP
+
+(define_attr "isa"
+  "mov,movw, rjmp,jmp, ijmp,eijmp,
+   standard"
+  (const_string "standard"))
+
+(define_attr "enabled" ""
+  (cond [(eq_attr "isa" "standard")
+         (const_int 1)
+         
+         (and (eq_attr "isa" "mov")
+              (match_test "!AVR_HAVE_MOVW"))
+         (const_int 1)
+
+         (and (eq_attr "isa" "movw")
+              (match_test "AVR_HAVE_MOVW"))
+         (const_int 1)
+         
+         (and (eq_attr "isa" "rjmp")
+              (match_test "!AVR_HAVE_JMP_CALL"))
+         (const_int 1)
+
+         (and (eq_attr "isa" "jmp")
+              (match_test "AVR_HAVE_JMP_CALL"))
+         (const_int 1)
+         
+         (and (eq_attr "isa" "ijmp")
+              (match_test "!AVR_HAVE_EIJMP_EICALL"))
+         (const_int 1)
+
+         (and (eq_attr "isa" "eijmp")
+              (match_test "AVR_HAVE_EIJMP_EICALL"))
+         (const_int 1)
+         ] (const_int 0)))
+
+
 ;; Define mode iterators
 (define_mode_iterator QIHI  [(QI "") (HI "")])
 (define_mode_iterator QIHI2 [(QI "") (HI "")])
    (set_attr "cc" "set_czn,set_n,set_czn")])
 
 (define_insn "negsi2"
-  [(set (match_operand:SI 0 "register_operand"       "=!d,r,&r")
-       (neg:SI (match_operand:SI 1 "register_operand" "0,0,r")))]
+  [(set (match_operand:SI 0 "register_operand"       "=!d,r,&r,&r")
+        (neg:SI (match_operand:SI 1 "register_operand" "0,0,r ,r")))]
   ""
   "@
        com %D0\;com %C0\;com %B0\;neg %A0\;sbci %B0,lo8(-1)\;sbci %C0,lo8(-1)\;sbci %D0,lo8(-1)
        com %D0\;com %C0\;com %B0\;com %A0\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__
-       clr %A0\;clr %B0\;{clr %C0\;clr %D0|movw %C0,%A0}\;sub %A0,%A1\;sbc %B0,%B1\;sbc %C0,%C1\;sbc %D0,%D1"
-  [(set_attr_alternative "length"
-                        [(const_int 7)
-                         (const_int 8)
-                         (if_then_else (eq_attr "mcu_have_movw" "yes")
-                                       (const_int 7)
-                                       (const_int 8))])
-   (set_attr "cc" "set_czn,set_n,set_czn")])
+       clr %A0\;clr %B0\;clr %C0\;clr %D0\;sub %A0,%A1\;sbc %B0,%B1\;sbc %C0,%C1\;sbc %D0,%D1
+       clr %A0\;clr %B0\;movw %C0,%A0\;sub %A0,%A1\;sbc %B0,%B1\;sbc %C0,%C1\;sbc %D0,%D1"
+  [(set_attr "length" "7,8,8,7")
+   (set_attr "isa"    "*,*,mov,movw")
+   (set_attr "cc" "set_czn,set_n,set_czn,set_czn")])
 
 (define_insn "negsf2"
   [(set (match_operand:SF 0 "register_operand" "=d,r")
    (set_attr "cc" "set_n,set_n")])
 
 (define_insn "extendhisi2"
-  [(set (match_operand:SI 0 "register_operand"                               "=r,r")
-        (sign_extend:SI (match_operand:HI 1 "combine_pseudo_register_operand" "0,*r")))]
+  [(set (match_operand:SI 0 "register_operand"                               "=r,r ,r")
+        (sign_extend:SI (match_operand:HI 1 "combine_pseudo_register_operand" "0,*r,*r")))]
   ""
   "@
        clr %C0\;sbrc %B0,7\;com %C0\;mov %D0,%C0
-       {mov %A0,%A1\;mov %B0,%B1|movw %A0,%A1}\;clr %C0\;sbrc %B0,7\;com %C0\;mov %D0,%C0"
-  [(set_attr_alternative "length"
-                        [(const_int 4)
-                         (if_then_else (eq_attr "mcu_have_movw" "yes")
-                                       (const_int 5)
-                                       (const_int 6))])
-   (set_attr "cc" "set_n,set_n")])
+       mov %A0,%A1\;mov %B0,%B1\;clr %C0\;sbrc %B0,7\;com %C0\;mov %D0,%C0
+       movw %A0,%A1\;clr %C0\;sbrc %B0,7\;com %C0\;mov %D0,%C0"
+  [(set_attr "length" "4,6,5")
+   (set_attr "isa" "*,mov,movw")
+   (set_attr "cc" "set_n")])
 
 ;; xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x xx<---x
 ;; zero extend
        (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")
+                     (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
                                    (const_int 2)
                                    (const_int 4))))
    (set_attr "cc" "clobber")])
        (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")
+                     (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
                                    (const_int 2)
                                    (const_int 4))))
    (set_attr "cc" "clobber")])
   [(set (pc)
         (label_ref (match_operand 0 "" "")))]
   ""
-  "*{
-  if (AVR_HAVE_JMP_CALL && get_attr_length (insn) != 1)
-    return AS1 (jmp,%x0);
-  return AS1 (rjmp,%x0);
-}"
+  {
+    return AVR_HAVE_JMP_CALL && get_attr_length (insn) != 1
+           ? "jmp %x0"
+           : "rjmp %x0";
+  }
   [(set (attr "length")
        (if_then_else (match_operand 0 "symbol_ref_operand" "") 
-               (if_then_else (eq_attr "mcu_mega" "no")
-                             (const_int 1)
-                             (const_int 2))
-               (if_then_else (and (ge (minus (pc) (match_dup 0)) (const_int -2047))
-                                  (le (minus (pc) (match_dup 0)) (const_int 2047)))
-                             (const_int 1)
-                             (const_int 2))))
+                      (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
+                                    (const_int 1)
+                                    (const_int 2))
+                      (if_then_else (and (ge (minus (pc)
+                                                    (match_dup 0))
+                                             (const_int -2047))
+                                         (le (minus (pc)
+                                                    (match_dup 0))
+                                             (const_int 2047)))
+                                    (const_int 1)
+                                    (const_int 2))))
    (set_attr "cc" "none")])
 
 ;; call
     %!ijmp
     %~jmp %x0"
   [(set_attr "cc" "clobber")
-   (set_attr_alternative "length"
-                         [(const_int 1)
-                          (if_then_else (eq_attr "mcu_mega" "yes")
-                                        (const_int 2)
-                                        (const_int 1))
-                          (const_int 1)
-                          (if_then_else (eq_attr "mcu_mega" "yes")
-                                        (const_int 2)
-                                        (const_int 1))])])
+   (set_attr "length" "1,*,1,*")
+   (set_attr "adjust_len" "*,call,*,call")])
 
 (define_insn "call_value_insn"
   [(parallel[(set (match_operand 0 "register_operand"                   "=r,r,r,r")
     %!ijmp
     %~jmp %x1"
   [(set_attr "cc" "clobber")
-   (set_attr_alternative "length"
-                         [(const_int 1)
-                          (if_then_else (eq_attr "mcu_mega" "yes")
-                                        (const_int 2)
-                                        (const_int 1))
-                          (const_int 1)
-                          (if_then_else (eq_attr "mcu_mega" "yes")
-                                        (const_int 2)
-                                        (const_int 1))])])
+   (set_attr "length" "1,*,1,*")
+   (set_attr "adjust_len" "*,call,*,call")])
 
 (define_insn "nop"
   [(const_int 0)]
 ; indirect jump
 
 (define_expand "indirect_jump"
-  [(set (pc) (match_operand:HI 0 "nonmemory_operand" ""))]
+  [(set (pc)
+        (match_operand:HI 0 "nonmemory_operand" ""))]
   ""
-  " if ((!AVR_HAVE_JMP_CALL) && !register_operand(operand0, HImode))
-    {
-      operands[0] = copy_to_mode_reg(HImode, operand0);
-    }"
-)
+  {
+    if (!AVR_HAVE_JMP_CALL && !register_operand (operands[0], HImode))
+      {
+        operands[0] = copy_to_mode_reg (HImode, operands[0]);
+      }
+  })
 
 ; indirect jump
-(define_insn "*jcindirect_jump"
-  [(set (pc) (match_operand:HI 0 "immediate_operand" "i"))]
+(define_insn "*indirect_jump"
+  [(set (pc)
+        (match_operand:HI 0 "nonmemory_operand" "i,i,!z,*r,z"))]
   ""
-  "%~jmp %x0"
-  [(set_attr "length" "2")
-   (set_attr "cc" "none")])
-
-;;
-(define_insn "*njcindirect_jump"
-  [(set (pc) (match_operand:HI 0 "register_operand" "!z,*r"))]
-  "!AVR_HAVE_EIJMP_EICALL"
   "@
+       rjmp %x0
+       jmp %x0
        ijmp
-       push %A0\;push %B0\;ret"
-  [(set_attr "length" "1,3")
-   (set_attr "cc" "none,none")])
-
-(define_insn "*indirect_jump_avr6"
-  [(set (pc) (match_operand:HI 0 "register_operand" "z"))]
-  "AVR_HAVE_EIJMP_EICALL"
-  "eijmp"
-  [(set_attr "length" "1")
+       push %A0\;push %B0\;ret
+       eijmp"
+  [(set_attr "length" "1,2,1,3,1")
+   (set_attr "isa" "rjmp,jmp,ijmp,ijmp,eijmp")
    (set_attr "cc" "none")])
 
 ;; table jump
 ;; For entries in jump table see avr_output_addr_vec_elt.
 
-;; Table made from "rjmp .L<n>" instructions for <= 8K devices.
-(define_insn "*tablejump_rjmp"
+;; Table made from
+;;    "rjmp .L<n>"   instructions for <= 8K devices
+;;    ".word gs(.L<n>)" addresses for >  8K devices
+(define_insn "*tablejump"
   [(set (pc)
-        (unspec:HI [(match_operand:HI 0 "register_operand" "!z,*r")]
+        (unspec:HI [(match_operand:HI 0 "register_operand" "!z,*r,z")]
                    UNSPEC_INDEX_JMP))
    (use (label_ref (match_operand 1 "" "")))
    (clobber (match_dup 0))]
-  "!AVR_HAVE_JMP_CALL"
+  ""
   "@
        ijmp
-       push %A0\;push %B0\;ret"
-  [(set_attr "length" "1,3")
-   (set_attr "cc" "none,none")])
-
-;; Move the common piece of code to libgcc.
-;; Table made from ".word gs(.L<n>)" addresses for > 8K devices.
-;; Read jump address from table and perform indirect jump.
-(define_insn "*tablejump_lib"
-  [(set (pc)
-        (unspec:HI [(match_operand:HI 0 "register_operand" "z")]
-                   UNSPEC_INDEX_JMP))
-   (use (label_ref (match_operand 1 "" "")))
-   (clobber (match_dup 0))]
-  "AVR_HAVE_JMP_CALL"
-  "jmp __tablejump2__"
-  [(set_attr "length" "2")
-   (set_attr "cc" "clobber")])
+       push %A0\;push %B0\;ret
+       jmp __tablejump2__"
+  [(set_attr "length" "1,3,2")
+   (set_attr "isa" "rjmp,rjmp,jmp")
+   (set_attr "cc" "none,none,clobber")])
 
 
 (define_expand "casesi"
   "* return avr_out_sbxx_branch (insn, operands);"
   [(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))))
+                           (le (minus (pc) (match_dup 3)) (const_int 2046)))
+                      (const_int 2)
+                      (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
+                                    (const_int 2)
+                                    (const_int 4))))
    (set_attr "cc" "clobber")])
 
 ;; Tests of bit 7 are pessimized to sign tests, so we need this too...
 }
   [(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))))
+                           (le (minus (pc) (match_dup 2)) (const_int 2046)))
+                      (const_int 2)
+                      (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
+                                    (const_int 2)
+                                    (const_int 4))))
    (set_attr "cc" "clobber")])
 
 ;; Upper half of the I/O space - read port to __tmp_reg__ and use sbrc/sbrs.
   "* return avr_out_sbxx_branch (insn, operands);"
   [(set (attr "length")
        (if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
-                          (le (minus (pc) (match_dup 3)) (const_int 2045)))
-                     (const_int 3)
-                     (if_then_else (eq_attr "mcu_mega" "no")
-                                   (const_int 3)
-                                   (const_int 5))))
+                           (le (minus (pc) (match_dup 3)) (const_int 2045)))
+                      (const_int 3)
+                      (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
+                                    (const_int 3)
+                                    (const_int 5))))
    (set_attr "cc" "clobber")])
 
 (define_insn "*sbix_branch_tmp_bit7"
        (if_then_else (and (ge (minus (pc) (match_dup 2)) (const_int -2046))
                           (le (minus (pc) (match_dup 2)) (const_int 2045)))
                      (const_int 3)
-                     (if_then_else (eq_attr "mcu_mega" "no")
+                      (if_then_else (match_test "!AVR_HAVE_JMP_CALL")
                                    (const_int 3)
                                    (const_int 5))))
    (set_attr "cc" "clobber")])
 ;;  Library prologue saves
 (define_insn "call_prologue_saves"
   [(unspec_volatile:HI [(const_int 0)] UNSPECV_PROLOGUE_SAVES)
-   (match_operand:HI 0 "immediate_operand" "")
-   (set (reg:HI REG_SP) (minus:HI 
-                           (reg:HI REG_SP)
-                           (match_operand:HI 1 "immediate_operand" "")))
+   (match_operand:HI 0 "immediate_operand" "i,i")
+   (set (reg:HI REG_SP)
+        (minus:HI (reg:HI REG_SP)
+                  (match_operand:HI 1 "immediate_operand" "i,i")))
    (use (reg:HI REG_X))
    (clobber (reg:HI REG_Z))]
   ""
        ldi r31,hi8(gs(1f))
        %~jmp __prologue_saves__+((18 - %0) * 2)
 1:"
-  [(set_attr_alternative "length"
-                        [(if_then_else (eq_attr "mcu_mega" "yes")
-                                       (const_int 6)
-                                       (const_int 5))])
-  (set_attr "cc" "clobber")
-  ])
+  [(set_attr "length" "5,6")
+   (set_attr "cc" "clobber")
+   (set_attr "isa" "rjmp,jmp")])
   
 ;  epilogue  restores using library
 (define_insn "epilogue_restores"
   [(unspec_volatile:QI [(const_int 0)] UNSPECV_EPILOGUE_RESTORES)
-   (set (reg:HI REG_Y ) (plus:HI 
-                           (reg:HI REG_Y)
-                           (match_operand:HI 0 "immediate_operand" ""))) 
-   (set (reg:HI REG_SP) (reg:HI REG_Y))
-   (clobber  (reg:QI REG_Z))]
+   (set (reg:HI REG_Y)
+        (plus:HI (reg:HI REG_Y)
+                 (match_operand:HI 0 "immediate_operand" "i,i")))
+   (set (reg:HI REG_SP)
+        (plus:HI (reg:HI REG_Y)
+                 (match_dup 0)))
+   (clobber (reg:QI REG_Z))]
   ""
   "ldi r30, lo8(%0)
        %~jmp __epilogue_restores__ + ((18 - %0) * 2)"
-  [(set_attr_alternative "length"
-                        [(if_then_else (eq_attr "mcu_mega" "yes")
-                                       (const_int 3)
-                                       (const_int 2))])
-  (set_attr "cc" "clobber")
-  ])
+  [(set_attr "length" "2,3")
+   (set_attr "cc" "clobber")
+   (set_attr "isa" "rjmp,jmp")])
   
 ; return
 (define_insn "return"
 (define_expand "prologue"
   [(const_int 0)]
   ""
-  "
   {
     expand_prologue (); 
     DONE;
-  }")
+  })
 
 (define_expand "epilogue"
   [(const_int 0)]