avr-protos.h (extra_constraint): Delete.
* config/avr/avr-protos.h (extra_constraint): Delete. (extra_constraint_Q): New declaration. * config/avr/constraints.md: New file. * config/avr/avr.md: Include it. (REG_X, REG_Y, REG_Z, REG_W): New constants. (TMP_REGNO, ZERO_REGNO): Likewise. (UNSPEC_STRLEN, UNSPEC_INDEX_JMP): Likewise. * config/avr/avr.c (avr_reg_class_from_letter): Delete. (extra_constraint): Delete. (extra_constraint_Q): Test for memory constraint 'Q'. * config/avr/avr.h (REG_X,REG_Y,REG_Z,REG_W): Delete. (REG_CLASS_FROM_LETTER): Delete. (CONST_OK_FOR_LETTER_P): Delete. (CONST_DOUBLE_OK_FOR_LETTER_P): Delete. (EXTRA_CONSTRAINT): Delete. (TMP_REGNO): Delete. (ZERO_REGNO): Delete. From-SVN: r112352
This commit is contained in:
parent
8cb86b657c
commit
2d67effa46
5 changed files with 160 additions and 108 deletions
|
@ -1,6 +1,7 @@
|
|||
/* Prototypes for exported functions defined in avr.c
|
||||
|
||||
Copyright (C) 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
|
||||
Copyright (C) 2000, 2001, 2002, 2003, 2004, 2006
|
||||
Free Software Foundation, Inc.
|
||||
Contributed by Denis Chertykov (denisc@overta.ru)
|
||||
|
||||
This file is part of GCC.
|
||||
|
@ -92,7 +93,7 @@ extern void avr_output_addr_vec_elt (FILE *stream, int value);
|
|||
extern const char *avr_out_sbxx_branch (rtx insn, rtx operands[]);
|
||||
|
||||
extern enum reg_class preferred_reload_class (rtx x, enum reg_class class);
|
||||
extern int extra_constraint (rtx x, int c);
|
||||
extern int extra_constraint_Q (rtx x);
|
||||
extern rtx legitimize_address (rtx x, rtx oldx, enum machine_mode mode);
|
||||
extern int adjust_insn_length (rtx insn, int len);
|
||||
extern rtx avr_libcall_value (enum machine_mode mode);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* Subroutines for insn-output.c for ATMEL AVR micro controllers
|
||||
Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2005
|
||||
Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2005, 2006
|
||||
Free Software Foundation, Inc.
|
||||
Contributed by Denis Chertykov (denisc@overta.ru)
|
||||
|
||||
|
@ -324,35 +324,6 @@ avr_regno_reg_class (int r)
|
|||
return ALL_REGS;
|
||||
}
|
||||
|
||||
|
||||
/* A C expression which defines the machine-dependent operand
|
||||
constraint letters for register classes. If C is such a
|
||||
letter, the value should be the register class corresponding to
|
||||
it. Otherwise, the value should be `NO_REGS'. The register
|
||||
letter `r', corresponding to class `GENERAL_REGS', will not be
|
||||
passed to this macro; you do not need to handle it. */
|
||||
|
||||
enum reg_class
|
||||
avr_reg_class_from_letter (int c)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case 't' : return R0_REG;
|
||||
case 'b' : return BASE_POINTER_REGS;
|
||||
case 'e' : return POINTER_REGS;
|
||||
case 'w' : return ADDW_REGS;
|
||||
case 'd' : return LD_REGS;
|
||||
case 'l' : return NO_LD_REGS;
|
||||
case 'a' : return SIMPLE_LD_REGS;
|
||||
case 'x' : return POINTER_X_REGS;
|
||||
case 'y' : return POINTER_Y_REGS;
|
||||
case 'z' : return POINTER_Z_REGS;
|
||||
case 'q' : return STACK_REG;
|
||||
default: break;
|
||||
}
|
||||
return NO_REGS;
|
||||
}
|
||||
|
||||
/* Return nonzero if FUNC is a naked function. */
|
||||
|
||||
static int
|
||||
|
@ -5475,48 +5446,35 @@ avr_address_cost (rtx x)
|
|||
return 4;
|
||||
}
|
||||
|
||||
/* EXTRA_CONSTRAINT helper */
|
||||
/* Test for extra memory constraint 'Q'.
|
||||
It's a memory address based on Y or Z pointer with valid displacement. */
|
||||
|
||||
int
|
||||
extra_constraint (rtx x, int c)
|
||||
extra_constraint_Q (rtx x)
|
||||
{
|
||||
if (c == 'Q'
|
||||
&& GET_CODE (x) == MEM
|
||||
&& GET_CODE (XEXP (x,0)) == PLUS)
|
||||
if (GET_CODE (XEXP (x,0)) == PLUS
|
||||
&& REG_P (XEXP (XEXP (x,0), 0))
|
||||
&& GET_CODE (XEXP (XEXP (x,0), 1)) == CONST_INT
|
||||
&& (INTVAL (XEXP (XEXP (x,0), 1))
|
||||
<= MAX_LD_OFFSET (GET_MODE (x))))
|
||||
{
|
||||
if (TARGET_ALL_DEBUG)
|
||||
{
|
||||
fprintf (stderr, ("extra_constraint:\n"
|
||||
"reload_completed: %d\n"
|
||||
"reload_in_progress: %d\n"),
|
||||
reload_completed, reload_in_progress);
|
||||
debug_rtx (x);
|
||||
}
|
||||
if (GET_CODE (x) == MEM
|
||||
&& GET_CODE (XEXP (x,0)) == PLUS
|
||||
&& REG_P (XEXP (XEXP (x,0), 0))
|
||||
&& GET_CODE (XEXP (XEXP (x,0), 1)) == CONST_INT
|
||||
&& (INTVAL (XEXP (XEXP (x,0), 1))
|
||||
<= MAX_LD_OFFSET (GET_MODE (x))))
|
||||
rtx xx = XEXP (XEXP (x,0), 0);
|
||||
int regno = REGNO (xx);
|
||||
if (TARGET_ALL_DEBUG)
|
||||
{
|
||||
rtx xx = XEXP (XEXP (x,0), 0);
|
||||
int regno = REGNO (xx);
|
||||
if (TARGET_ALL_DEBUG)
|
||||
{
|
||||
fprintf (stderr, ("extra_constraint:\n"
|
||||
"reload_completed: %d\n"
|
||||
"reload_in_progress: %d\n"),
|
||||
reload_completed, reload_in_progress);
|
||||
debug_rtx (x);
|
||||
}
|
||||
if (regno >= FIRST_PSEUDO_REGISTER)
|
||||
return 1; /* allocate pseudos */
|
||||
else if (regno == REG_Z || regno == REG_Y)
|
||||
return 1; /* strictly check */
|
||||
else if (xx == frame_pointer_rtx
|
||||
|| xx == arg_pointer_rtx)
|
||||
return 1; /* XXX frame & arg pointer checks */
|
||||
fprintf (stderr, ("extra_constraint:\n"
|
||||
"reload_completed: %d\n"
|
||||
"reload_in_progress: %d\n"),
|
||||
reload_completed, reload_in_progress);
|
||||
debug_rtx (x);
|
||||
}
|
||||
if (regno >= FIRST_PSEUDO_REGISTER)
|
||||
return 1; /* allocate pseudos */
|
||||
else if (regno == REG_Z || regno == REG_Y)
|
||||
return 1; /* strictly check */
|
||||
else if (xx == frame_pointer_rtx
|
||||
|| xx == arg_pointer_rtx)
|
||||
return 1; /* XXX frame & arg pointer checks */
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* Definitions of target machine for GNU compiler,
|
||||
for ATMEL AVR at90s8515, ATmega103/103L, ATmega603/603L microcontrollers.
|
||||
Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
|
||||
Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
|
||||
Free Software Foundation, Inc.
|
||||
Contributed by Denis Chertykov (denisc@overta.ru)
|
||||
|
||||
|
@ -206,11 +206,6 @@ enum reg_class {
|
|||
"GENERAL_REGS", /* r0 - r31 */ \
|
||||
"ALL_REGS" }
|
||||
|
||||
#define REG_X 26
|
||||
#define REG_Y 28
|
||||
#define REG_Z 30
|
||||
#define REG_W 24
|
||||
|
||||
#define REG_CLASS_CONTENTS { \
|
||||
{0x00000000,0x00000000}, /* NO_REGS */ \
|
||||
{0x00000001,0x00000000}, /* R0_REG */ \
|
||||
|
@ -238,8 +233,6 @@ enum reg_class {
|
|||
|
||||
#define INDEX_REG_CLASS NO_REGS
|
||||
|
||||
#define REG_CLASS_FROM_LETTER(C) avr_reg_class_from_letter(C)
|
||||
|
||||
#define REGNO_OK_FOR_BASE_P(r) (((r) < FIRST_PSEUDO_REGISTER \
|
||||
&& ((r) == REG_X \
|
||||
|| (r) == REG_Y \
|
||||
|
@ -262,23 +255,6 @@ enum reg_class {
|
|||
|
||||
#define CLASS_MAX_NREGS(CLASS, MODE) class_max_nregs (CLASS, MODE)
|
||||
|
||||
#define CONST_OK_FOR_LETTER_P(VALUE, C) \
|
||||
((C) == 'I' ? (VALUE) >= 0 && (VALUE) <= 63 : \
|
||||
(C) == 'J' ? (VALUE) <= 0 && (VALUE) >= -63: \
|
||||
(C) == 'K' ? (VALUE) == 2 : \
|
||||
(C) == 'L' ? (VALUE) == 0 : \
|
||||
(C) == 'M' ? (VALUE) >= 0 && (VALUE) <= 0xff : \
|
||||
(C) == 'N' ? (VALUE) == -1: \
|
||||
(C) == 'O' ? (VALUE) == 8 || (VALUE) == 16 || (VALUE) == 24: \
|
||||
(C) == 'P' ? (VALUE) == 1 : \
|
||||
0)
|
||||
|
||||
#define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C) \
|
||||
((C) == 'G' ? (VALUE) == CONST0_RTX (SFmode) \
|
||||
: 0)
|
||||
|
||||
#define EXTRA_CONSTRAINT(x, c) extra_constraint(x, c)
|
||||
|
||||
#define STACK_PUSH_CODE POST_DEC
|
||||
|
||||
#define STACK_GROWS_DOWNWARD
|
||||
|
@ -841,10 +817,4 @@ extern int avr_case_values_threshold;
|
|||
#define OUT_AS2(a,b,c) output_asm_insn (AS2(a,b,c), operands)
|
||||
#define CR_TAB "\n\t"
|
||||
|
||||
/* Temporary register r0 */
|
||||
#define TMP_REGNO 0
|
||||
|
||||
/* zero register r1 */
|
||||
#define ZERO_REGNO 1
|
||||
|
||||
#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
;; -*- Mode: Scheme -*-
|
||||
;; Machine description for GNU compiler,
|
||||
;; for ATMEL AVR micro controllers.
|
||||
;; Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2005
|
||||
;; Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2005, 2006
|
||||
;; Free Software Foundation, Inc.
|
||||
;; Contributed by Denis Chertykov (denisc@overta.ru)
|
||||
|
||||
|
@ -36,8 +36,20 @@
|
|||
|
||||
;; UNSPEC usage:
|
||||
;; 0 Length of a string, see "strlenhi".
|
||||
;; 1 Read from a word address in program memory, see "casesi".
|
||||
;; 1 Jump by register pair Z or by table addressed by Z, see "casesi".
|
||||
|
||||
(define_constants
|
||||
[(REG_X 26)
|
||||
(REG_Y 28)
|
||||
(REG_Z 30)
|
||||
(REG_W 24)
|
||||
(TMP_REGNO 0) ; temporary register r0
|
||||
(ZERO_REGNO 1) ; zero register r1
|
||||
(UNSPEC_STRLEN 0)
|
||||
(UNSPEC_INDEX_JMP 1)])
|
||||
|
||||
(include "constraints.md")
|
||||
|
||||
;; Condition code settings.
|
||||
(define_attr "cc" "none,set_czn,set_zn,set_n,compare,clobber"
|
||||
(const_string "none"))
|
||||
|
@ -482,7 +494,8 @@
|
|||
[(set (match_dup 4)
|
||||
(unspec:HI [(match_operand:BLK 1 "memory_operand" "")
|
||||
(match_operand:QI 2 "const_int_operand" "")
|
||||
(match_operand:HI 3 "immediate_operand" "")] 0))
|
||||
(match_operand:HI 3 "immediate_operand" "")]
|
||||
UNSPEC_STRLEN))
|
||||
(set (match_dup 4) (plus:HI (match_dup 4)
|
||||
(const_int -1)))
|
||||
(set (match_operand:HI 0 "register_operand" "")
|
||||
|
@ -503,7 +516,8 @@
|
|||
[(set (match_operand:HI 0 "register_operand" "=e")
|
||||
(unspec:HI [(mem:BLK (match_operand:HI 1 "register_operand" "%0"))
|
||||
(const_int 0)
|
||||
(match_operand:HI 2 "immediate_operand" "i")] 0))]
|
||||
(match_operand:HI 2 "immediate_operand" "i")]
|
||||
UNSPEC_STRLEN))]
|
||||
""
|
||||
"ld __tmp_reg__,%a0+
|
||||
tst __tmp_reg__
|
||||
|
@ -2180,7 +2194,8 @@
|
|||
|
||||
;; Table made from "rjmp" instructions for <=8K devices.
|
||||
(define_insn "*tablejump_rjmp"
|
||||
[(set (pc) (unspec:HI [(match_operand:HI 0 "register_operand" "!z,*r")] 1))
|
||||
[(set (pc) (unspec:HI [(match_operand:HI 0 "register_operand" "!z,*r")]
|
||||
UNSPEC_INDEX_JMP))
|
||||
(use (label_ref (match_operand 1 "" "")))
|
||||
(clobber (match_dup 0))]
|
||||
"!AVR_MEGA"
|
||||
|
@ -2192,7 +2207,8 @@
|
|||
|
||||
;; Not a prologue, but similar idea - move the common piece of code to libgcc.
|
||||
(define_insn "*tablejump_lib"
|
||||
[(set (pc) (unspec:HI [(match_operand:HI 0 "register_operand" "z")] 1))
|
||||
[(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_MEGA && TARGET_CALL_PROLOGUES"
|
||||
|
@ -2201,7 +2217,8 @@
|
|||
(set_attr "cc" "clobber")])
|
||||
|
||||
(define_insn "*tablejump_enh"
|
||||
[(set (pc) (unspec:HI [(match_operand:HI 0 "register_operand" "z")] 1))
|
||||
[(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_MEGA && AVR_ENHANCED"
|
||||
|
@ -2215,7 +2232,8 @@
|
|||
(set_attr "cc" "clobber")])
|
||||
|
||||
(define_insn "*tablejump"
|
||||
[(set (pc) (unspec:HI [(match_operand:HI 0 "register_operand" "z")] 1))
|
||||
[(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_MEGA"
|
||||
|
@ -2248,7 +2266,7 @@
|
|||
(set (match_dup 6)
|
||||
(plus:HI (match_dup 6) (label_ref (match_operand:HI 3 "" ""))))
|
||||
|
||||
(parallel [(set (pc) (unspec:HI [(match_dup 6)] 1))
|
||||
(parallel [(set (pc) (unspec:HI [(match_dup 6)] UNSPEC_INDEX_JMP))
|
||||
(use (label_ref (match_dup 3)))
|
||||
(clobber (match_dup 6))])]
|
||||
""
|
||||
|
|
105
gcc/config/avr/constraints.md
Normal file
105
gcc/config/avr/constraints.md
Normal file
|
@ -0,0 +1,105 @@
|
|||
;; Constraint definitions for ATMEL AVR micro controllers.
|
||||
;; Copyright (C) 2006 Free Software Foundation, Inc.
|
||||
;;
|
||||
;; This file is part of GCC.
|
||||
;;
|
||||
;; GCC is free software; you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation; either version 2, or (at your option)
|
||||
;; any later version.
|
||||
;;
|
||||
;; GCC is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
;;
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with GCC; see the file COPYING. If not, write to
|
||||
;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,
|
||||
;; Boston, MA 02110-1301, USA.
|
||||
|
||||
;; Register constraints
|
||||
|
||||
(define_register_constraint "t" "R0_REG"
|
||||
"Temporary register r0")
|
||||
|
||||
(define_register_constraint "b" "BASE_POINTER_REGS"
|
||||
"Base pointer registers (r28--r31)")
|
||||
|
||||
(define_register_constraint "e" "POINTER_REGS"
|
||||
"Pointer registers (r26--r31)")
|
||||
|
||||
(define_register_constraint "w" "ADDW_REGS"
|
||||
"Registers from r24 to r31. These registers
|
||||
can be used in @samp{adiw} command.")
|
||||
|
||||
(define_register_constraint "d" "LD_REGS"
|
||||
"Registers from r16 to r31.")
|
||||
|
||||
(define_register_constraint "l" "NO_LD_REGS"
|
||||
"Registers from r0 to r15.")
|
||||
|
||||
(define_register_constraint "a" "SIMPLE_LD_REGS"
|
||||
"Registers from r16 to r23.")
|
||||
|
||||
(define_register_constraint "x" "POINTER_X_REGS"
|
||||
"Register pair X (r27:r26).")
|
||||
|
||||
(define_register_constraint "y" "POINTER_Y_REGS"
|
||||
"Register pair Y (r29:r28).")
|
||||
|
||||
(define_register_constraint "z" "POINTER_Z_REGS"
|
||||
"Register pair Z (r31:r30).")
|
||||
|
||||
(define_register_constraint "q" "STACK_REG"
|
||||
"Stack pointer register (SPH:SPL).")
|
||||
|
||||
(define_constraint "I"
|
||||
"Integer constant in the range 0 @dots{} 63."
|
||||
(and (match_code "const_int")
|
||||
(match_test "ival >= 0 && ival <= 63")))
|
||||
|
||||
(define_constraint "J"
|
||||
"Integer constant in the range -63 @dots{} 0."
|
||||
(and (match_code "const_int")
|
||||
(match_test "ival <= 0 && ival >= -63")))
|
||||
|
||||
(define_constraint "K"
|
||||
"Integer constant 2."
|
||||
(and (match_code "const_int")
|
||||
(match_test "ival == 2")))
|
||||
|
||||
(define_constraint "L"
|
||||
"Zero."
|
||||
(and (match_code "const_int")
|
||||
(match_test "ival == 0")))
|
||||
|
||||
(define_constraint "M"
|
||||
"Integer constant in the range 0 @dots{} 0xff."
|
||||
(and (match_code "const_int")
|
||||
(match_test "ival >= 0 && ival <= 0xff")))
|
||||
|
||||
(define_constraint "N"
|
||||
"Constant integer @minus{}1."
|
||||
(and (match_code "const_int")
|
||||
(match_test "ival == -1")))
|
||||
|
||||
(define_constraint "O"
|
||||
"Constant integer 8, 16, or 24."
|
||||
(and (match_code "const_int")
|
||||
(match_test "ival == 8 || ival == 16 || ival == 24")))
|
||||
|
||||
(define_constraint "P"
|
||||
"Constant integer 1."
|
||||
(and (match_code "const_int")
|
||||
(match_test "ival == 1")))
|
||||
|
||||
(define_constraint "G"
|
||||
"Constant float 0."
|
||||
(and (match_code "const_double")
|
||||
(match_test "op == CONST0_RTX (SFmode)")))
|
||||
|
||||
(define_memory_constraint "Q"
|
||||
"A memory address based on X or Y pointer with displacement."
|
||||
(and (match_code "mem")
|
||||
(match_test "extra_constraint_Q (op)")))
|
Loading…
Add table
Reference in a new issue