stormy16-lib2.c (MIN_UNITS_PER_WORD): Provide a default definition.
* config/stormy16/stormy16-lib2.c (MIN_UNITS_PER_WORD): Provide a default definition. (LIBGCC2_UNITS_PER_WORD): Likewise. * config/stormy16/stormy16.c: Include df.h for the prototype for df_regs_ever_live_p. (xstormy16_expand_builtin_va_start): Convert the stack offset into a component_ref and then use POINTER_PLUS_EXPR to add it to the incoming_virtual_args_rtx. (xstormy16_gimplify_va_arg_expr): Rename to xstormy16_gimplify_va_arg_expr. Use POINTER_PLUS_EXPR when performing pointer arithmetic. (TARGET_GIMPLIFY_VA_ARG_EXPR): Use renamed xstormy16_gimplify_va_arg_expr. Fix up some formatting issues. * config/stormy16/stormy16.c: (xstormy16_carry_plus_operand): Move to predicates.md. (xs_hi_general_operand): Likewise. (xs_hi_nonmemory_operand): Likewise. * config/stormy16/predicates.md: (xstormy16_carry_plus_operand): New predicate. (xs_hi_general_operand): New predicate. (xs_hi_nonmemory_operand): New predicate. * config/stormy16/stormy16-protos.h: (xstormy16_carry_plus_operand): Delete prototype. (xs_hi_general_operand): Likewise. (xs_hi_nonmemory_operand): Likewise. * config/storm16/stormy16.md (addhi3): Remove earlyclobber modifiers as they are no longer needed and they can trigger reload spill failures. * config/storm16/stormy16.md (ineqbranchsi): Replace match_dup with a match_operand in order to help reload. * config/storm16/stormy16.md (movhi_internal): Replace 'r' constraint with 'e' for the 8th alternative as this version of the mov.w instruction only accepts the lower 8 registers. From-SVN: r131822
This commit is contained in:
parent
d1f0728e65
commit
f84fe9b6f7
@ -1,3 +1,45 @@
|
||||
2008-01-24 Nick Clifton <nickc@redhat.com>
|
||||
|
||||
* config/stormy16/stormy16-lib2.c (MIN_UNITS_PER_WORD):
|
||||
Provide a default definition.
|
||||
(LIBGCC2_UNITS_PER_WORD): Likewise.
|
||||
|
||||
* config/stormy16/stormy16.c: Include df.h for the prototype
|
||||
for df_regs_ever_live_p.
|
||||
(xstormy16_expand_builtin_va_start): Convert the stack offset
|
||||
into a component_ref and then use POINTER_PLUS_EXPR to add it
|
||||
to the incoming_virtual_args_rtx.
|
||||
(xstormy16_gimplify_va_arg_expr): Rename to
|
||||
xstormy16_gimplify_va_arg_expr.
|
||||
Use POINTER_PLUS_EXPR when performing pointer arithmetic.
|
||||
(TARGET_GIMPLIFY_VA_ARG_EXPR): Use renamed
|
||||
xstormy16_gimplify_va_arg_expr.
|
||||
Fix up some formatting issues.
|
||||
|
||||
* config/stormy16/stormy16.c: (xstormy16_carry_plus_operand):
|
||||
Move to predicates.md.
|
||||
(xs_hi_general_operand): Likewise.
|
||||
(xs_hi_nonmemory_operand): Likewise.
|
||||
* config/stormy16/predicates.md:
|
||||
(xstormy16_carry_plus_operand): New predicate.
|
||||
(xs_hi_general_operand): New predicate.
|
||||
(xs_hi_nonmemory_operand): New predicate.
|
||||
* config/stormy16/stormy16-protos.h:
|
||||
(xstormy16_carry_plus_operand): Delete prototype.
|
||||
(xs_hi_general_operand): Likewise.
|
||||
(xs_hi_nonmemory_operand): Likewise.
|
||||
|
||||
* config/storm16/stormy16.md (addhi3): Remove earlyclobber
|
||||
modifiers as they are no longer needed and they can trigger
|
||||
reload spill failures.
|
||||
|
||||
* config/storm16/stormy16.md (ineqbranchsi): Replace match_dup
|
||||
with a match_operand in order to help reload.
|
||||
|
||||
* config/storm16/stormy16.md (movhi_internal): Replace 'r'
|
||||
constraint with 'e' for the 8th alternative as this version of
|
||||
the mov.w instruction only accepts the lower 8 registers.
|
||||
|
||||
2008-01-25 Uros Bizjak <ubizjak@gmail.com>
|
||||
|
||||
PR target/34856
|
||||
|
@ -143,3 +143,36 @@
|
||||
&& ! xstormy16_extra_constraint_p (op, 'Q')
|
||||
&& ! xstormy16_extra_constraint_p (op, 'R'));
|
||||
})
|
||||
|
||||
(define_predicate "xstormy16_carry_plus_operand"
|
||||
(match_code "plus")
|
||||
{
|
||||
return (GET_CODE (XEXP (op, 1)) == CONST_INT
|
||||
&& (INTVAL (XEXP (op, 1)) < -4 || INTVAL (XEXP (op, 1)) > 4));
|
||||
})
|
||||
|
||||
(define_predicate "xs_hi_general_operand"
|
||||
(match_code "const_int,reg,subreg,mem,symbol_ref,label_ref,const")
|
||||
{
|
||||
if ((GET_CODE (op) == CONST_INT)
|
||||
&& ((INTVAL (op) >= 32768) || (INTVAL (op) < -32768)))
|
||||
{
|
||||
error ("constant halfword load operand out of range");
|
||||
return false;
|
||||
}
|
||||
|
||||
return general_operand (op, mode);
|
||||
})
|
||||
|
||||
(define_predicate "xs_hi_nonmemory_operand"
|
||||
(match_code "const_int,reg,subreg,const")
|
||||
{
|
||||
if ((GET_CODE (op) == CONST_INT)
|
||||
&& ((INTVAL (op) >= 32768) || (INTVAL (op) < -32768)))
|
||||
{
|
||||
error ("constant arithmetic operand out of range");
|
||||
return false;
|
||||
}
|
||||
|
||||
return nonmemory_operand (op, mode);
|
||||
})
|
||||
|
@ -43,6 +43,23 @@
|
||||
#define ATTRIBUTE_HIDDEN
|
||||
#endif
|
||||
|
||||
#ifndef MIN_UNITS_PER_WORD
|
||||
#define MIN_UNITS_PER_WORD UNITS_PER_WORD
|
||||
#endif
|
||||
|
||||
#ifndef LIBGCC2_UNITS_PER_WORD
|
||||
# if MIN_UNITS_PER_WORD > 4
|
||||
# define LIBGCC2_UNITS_PER_WORD 8
|
||||
# elif (MIN_UNITS_PER_WORD > 2 \
|
||||
|| (MIN_UNITS_PER_WORD > 1 && LONG_LONG_TYPE_SIZE > 32))
|
||||
# define LIBGCC2_UNITS_PER_WORD 4
|
||||
# else
|
||||
# define LIBGCC2_UNITS_PER_WORD MIN_UNITS_PER_WORD
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#define word_type Wtype
|
||||
|
||||
#include "libgcc2.h"
|
||||
#undef int
|
||||
|
||||
|
@ -69,9 +69,6 @@ extern int short_memory_operand (rtx, enum machine_mode);
|
||||
extern int nonimmediate_nonstack_operand (rtx, enum machine_mode);
|
||||
extern enum reg_class xstormy16_secondary_reload_class
|
||||
(enum reg_class, enum machine_mode, rtx);
|
||||
extern int xstormy16_carry_plus_operand (rtx, enum machine_mode);
|
||||
extern int xs_hi_general_operand (rtx, enum machine_mode);
|
||||
extern int xs_hi_nonmemory_operand (rtx, enum machine_mode);
|
||||
extern enum reg_class xstormy16_preferred_reload_class (rtx, enum reg_class);
|
||||
extern int xstormy16_legitimate_address_p (enum machine_mode, rtx, int);
|
||||
extern void xstormy16_split_move (enum machine_mode, rtx, rtx);
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* Xstormy16 target functions.
|
||||
Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
|
||||
2006, 2007 Free Software Foundation, Inc.
|
||||
2006, 2007, 2008 Free Software Foundation, Inc.
|
||||
Contributed by Red Hat, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
@ -46,6 +46,7 @@ along with GCC; see the file COPYING3. If not see
|
||||
#include "tm_p.h"
|
||||
#include "langhooks.h"
|
||||
#include "tree-gimple.h"
|
||||
#include "df.h"
|
||||
#include "ggc.h"
|
||||
|
||||
static rtx emit_addhi3_postreload (rtx, rtx, rtx);
|
||||
@ -481,35 +482,6 @@ xstormy16_secondary_reload_class (enum reg_class class,
|
||||
return NO_REGS;
|
||||
}
|
||||
|
||||
/* Recognize a PLUS that needs the carry register. */
|
||||
int
|
||||
xstormy16_carry_plus_operand (rtx x, enum machine_mode mode ATTRIBUTE_UNUSED)
|
||||
{
|
||||
return (GET_CODE (x) == PLUS
|
||||
&& GET_CODE (XEXP (x, 1)) == CONST_INT
|
||||
&& (INTVAL (XEXP (x, 1)) < -4 || INTVAL (XEXP (x, 1)) > 4));
|
||||
}
|
||||
|
||||
/* Detect and error out on out-of-range constants for movhi. */
|
||||
int
|
||||
xs_hi_general_operand (rtx x, enum machine_mode mode ATTRIBUTE_UNUSED)
|
||||
{
|
||||
if ((GET_CODE (x) == CONST_INT)
|
||||
&& ((INTVAL (x) >= 32768) || (INTVAL (x) < -32768)))
|
||||
error ("constant halfword load operand out of range");
|
||||
return general_operand (x, mode);
|
||||
}
|
||||
|
||||
/* Detect and error out on out-of-range constants for addhi and subhi. */
|
||||
int
|
||||
xs_hi_nonmemory_operand (rtx x, enum machine_mode mode ATTRIBUTE_UNUSED)
|
||||
{
|
||||
if ((GET_CODE (x) == CONST_INT)
|
||||
&& ((INTVAL (x) >= 32768) || (INTVAL (x) < -32768)))
|
||||
error ("constant arithmetic operand out of range");
|
||||
return nonmemory_operand (x, mode);
|
||||
}
|
||||
|
||||
enum reg_class
|
||||
xstormy16_preferred_reload_class (rtx x, enum reg_class class)
|
||||
{
|
||||
@ -669,7 +641,7 @@ xstormy16_legitimate_address_p (enum machine_mode mode ATTRIBUTE_UNUSED,
|
||||
&& (! strict || REGNO (x) < FIRST_PSEUDO_REGISTER))
|
||||
return 1;
|
||||
|
||||
if (xstormy16_below100_symbol(x, mode))
|
||||
if (xstormy16_below100_symbol (x, mode))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
@ -759,7 +731,7 @@ xstormy16_extra_constraint_p (rtx x, int c)
|
||||
&& (INTVAL (x) == 0));
|
||||
|
||||
case 'W':
|
||||
return xstormy16_below100_operand(x, GET_MODE(x));
|
||||
return xstormy16_below100_operand (x, GET_MODE (x));
|
||||
|
||||
default:
|
||||
return 0;
|
||||
@ -1357,7 +1329,7 @@ xstormy16_expand_builtin_va_start (tree valist, rtx nextarg ATTRIBUTE_UNUSED)
|
||||
{
|
||||
tree f_base, f_count;
|
||||
tree base, count;
|
||||
tree t;
|
||||
tree t,u;
|
||||
|
||||
if (xstormy16_interrupt_function_p ())
|
||||
error ("cannot use va_start in interrupt function");
|
||||
@ -1370,8 +1342,9 @@ xstormy16_expand_builtin_va_start (tree valist, rtx nextarg ATTRIBUTE_UNUSED)
|
||||
NULL_TREE);
|
||||
|
||||
t = make_tree (TREE_TYPE (base), virtual_incoming_args_rtx);
|
||||
t = build2 (PLUS_EXPR, TREE_TYPE (base), t,
|
||||
build_int_cst (NULL_TREE, INCOMING_FRAME_SP_OFFSET));
|
||||
u = build_int_cst (NULL_TREE, INCOMING_FRAME_SP_OFFSET);
|
||||
u = fold_convert (TREE_TYPE (count), u);
|
||||
t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (base), t, u);
|
||||
t = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (base), base, t);
|
||||
TREE_SIDE_EFFECTS (t) = 1;
|
||||
expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
|
||||
@ -1388,8 +1361,8 @@ xstormy16_expand_builtin_va_start (tree valist, rtx nextarg ATTRIBUTE_UNUSED)
|
||||
Note: This algorithm is documented in stormy-abi. */
|
||||
|
||||
static tree
|
||||
xstormy16_expand_builtin_va_arg (tree valist, tree type, tree *pre_p,
|
||||
tree *post_p ATTRIBUTE_UNUSED)
|
||||
xstormy16_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p,
|
||||
tree *post_p ATTRIBUTE_UNUSED)
|
||||
{
|
||||
tree f_base, f_count;
|
||||
tree base, count;
|
||||
@ -1428,9 +1401,8 @@ xstormy16_expand_builtin_va_arg (tree valist, tree type, tree *pre_p,
|
||||
build1 (GOTO_EXPR, void_type_node, lab_fromstack),
|
||||
NULL_TREE);
|
||||
gimplify_and_add (t, pre_p);
|
||||
|
||||
t = fold_convert (ptr_type_node, count_tmp);
|
||||
t = build2 (PLUS_EXPR, ptr_type_node, base, t);
|
||||
|
||||
t = build2 (POINTER_PLUS_EXPR, ptr_type_node, base, count_tmp);
|
||||
t = build2 (GIMPLE_MODIFY_STMT, void_type_node, addr, t);
|
||||
gimplify_and_add (t, pre_p);
|
||||
|
||||
@ -1464,8 +1436,9 @@ xstormy16_expand_builtin_va_arg (tree valist, tree type, tree *pre_p,
|
||||
t = build2 (MINUS_EXPR, TREE_TYPE (count), count_tmp, t);
|
||||
t = build2 (PLUS_EXPR, TREE_TYPE (count), t,
|
||||
fold_convert (TREE_TYPE (count), size_tree));
|
||||
t = fold_convert (TREE_TYPE (base), fold (t));
|
||||
t = build2 (MINUS_EXPR, TREE_TYPE (base), base, t);
|
||||
t = fold_convert (TREE_TYPE (t), fold (t));
|
||||
t = fold_build1 (NEGATE_EXPR, TREE_TYPE (t), t);
|
||||
t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (base), base, t);
|
||||
t = build2 (GIMPLE_MODIFY_STMT, void_type_node, addr, t);
|
||||
gimplify_and_add (t, pre_p);
|
||||
|
||||
@ -2338,10 +2311,10 @@ xstormy16_init_builtins (void)
|
||||
}
|
||||
|
||||
static rtx
|
||||
xstormy16_expand_builtin(tree exp, rtx target,
|
||||
rtx subtarget ATTRIBUTE_UNUSED,
|
||||
enum machine_mode mode ATTRIBUTE_UNUSED,
|
||||
int ignore ATTRIBUTE_UNUSED)
|
||||
xstormy16_expand_builtin (tree exp, rtx target,
|
||||
rtx subtarget ATTRIBUTE_UNUSED,
|
||||
enum machine_mode mode ATTRIBUTE_UNUSED,
|
||||
int ignore ATTRIBUTE_UNUSED)
|
||||
{
|
||||
rtx op[10], args[10], pat, copyto[10], retval = 0;
|
||||
tree fndecl, argtree;
|
||||
@ -2669,7 +2642,7 @@ xstormy16_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
|
||||
#undef TARGET_EXPAND_BUILTIN_VA_START
|
||||
#define TARGET_EXPAND_BUILTIN_VA_START xstormy16_expand_builtin_va_start
|
||||
#undef TARGET_GIMPLIFY_VA_ARG_EXPR
|
||||
#define TARGET_GIMPLIFY_VA_ARG_EXPR xstormy16_expand_builtin_va_arg
|
||||
#define TARGET_GIMPLIFY_VA_ARG_EXPR xstormy16_gimplify_va_arg_expr
|
||||
|
||||
#undef TARGET_PROMOTE_FUNCTION_ARGS
|
||||
#define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_const_tree_true
|
||||
|
@ -185,7 +185,7 @@
|
||||
|
||||
(define_insn "movhi_internal"
|
||||
[(set (match_operand:HI 0 "nonimmediate_nonstack_operand" "=r,m,e,e,T,r,S,W,r")
|
||||
(match_operand:HI 1 "xs_hi_general_operand" "r,e,m,L,L,i,i,ir,W"))]
|
||||
(match_operand:HI 1 "xs_hi_general_operand" "r,e,m,L,L,i,i,ie,W"))]
|
||||
""
|
||||
"@
|
||||
mov %0,%1
|
||||
@ -304,11 +304,8 @@
|
||||
;; ::::::::::::::::::::
|
||||
|
||||
;; Addition
|
||||
; Operand 3 is marked earlyclobber because that helps reload
|
||||
; to generate better code---this pattern will never need the
|
||||
; carry register as an input, and some output reloads or input
|
||||
; reloads might need to use it. In fact, without the '&' reload
|
||||
; will fail in some cases.
|
||||
; Note - the early clobber modifier is no longer needed on operand 3
|
||||
; and in fact can cause some reload spill failures if it is present.
|
||||
; Note that the 'Z' constraint matches "add $reg,0", which reload
|
||||
; will occasionally emit. We avoid the "add $reg,imm" match because
|
||||
; it clobbers the carry.
|
||||
@ -316,7 +313,7 @@
|
||||
[(set (match_operand:HI 0 "register_operand" "=r,r,r,T,T,r,r,r")
|
||||
(plus:HI (match_operand:HI 1 "register_operand" "%0,0,0,0,0,0,0,0")
|
||||
(match_operand:HI 2 "xs_hi_nonmemory_operand" "O,P,Z,L,M,Ir,N,i")))
|
||||
(clobber (match_scratch:BI 3 "=X,X,X,&y,&y,&y,&y,&y"))]
|
||||
(clobber (match_scratch:BI 3 "=X,X,X,y,y,y,y,y"))]
|
||||
""
|
||||
"@
|
||||
inc %0,%o2
|
||||
@ -905,15 +902,11 @@
|
||||
"ri")])
|
||||
(label_ref (match_operand 0 "" ""))
|
||||
(pc)))
|
||||
;; Although I would greatly like the 'match_dup' in the following line
|
||||
;; to actually be a register constraint, there is (at the time of writing) no
|
||||
;; way for reload to insert an output reload on the edges out of a branch.
|
||||
;; If reload is fixed to use insert_insn_on_edge, this can be changed,
|
||||
;; preferably to a 'minus' operand that explains the actual operation, like:
|
||||
; (set (match_operand 5 "register_operand" "=2")
|
||||
; (minus:SI (match_operand 6 "register_operand" "2")
|
||||
; (match_operand 7 "register_operand" "3")))
|
||||
(clobber (match_dup 2))
|
||||
;; This clobber is problematic. Too many gcc optimizations will change
|
||||
;; operand 2 without changing the clobber. At the time of writing there
|
||||
;; is no way around this. :-( For an example try compiling:
|
||||
;; gcc.c-torture/compile/20000403-1.c -O3 -fomit-frame-pointer -funroll-loops
|
||||
(clobber (match_operand:SI 5 "register_operand" "=2"))
|
||||
(clobber (match_operand:BI 4 "" "=&y"))]
|
||||
""
|
||||
"#"
|
||||
|
Loading…
Reference in New Issue
Block a user