/* 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.
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);
/* 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)
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
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;
}
/* 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)
"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 */ \
#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 \
#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
#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
;; -*- 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)
;; 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"))
[(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" "")
[(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__
;; 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"
;; 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"
(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"
(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"
(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))])]
""
--- /dev/null
+;; 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)")))