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:
Denis Chertykov 2006-03-24 19:30:19 +03:00
parent 8cb86b657c
commit 2d67effa46
5 changed files with 160 additions and 108 deletions

View File

@ -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);

View File

@ -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;
}

View File

@ -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

View File

@ -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))])]
""

View 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)")))