Commit a32767e4 by David Mosberger Committed by Richard Henderson

extend.texi (Function Attributes): Document the IA-64 version of the "model" attribute.

        * doc/extend.texi (Function Attributes): Document the IA-64 version
        of the "model" attribute.

        * config/ia64/ia64.h (SYMBOL_FLAG_SMALL_ADDR): New macro.
        (SYMBOL_REF_SMALL_ADDR_P): Ditto.
        (PREDICATE_CODES): Mention "small_addr_symbolic_operand".

        * config/ia64/ia64.c (ia64_handle_model_attribute): New function.
        (ia64_encode_section_info): Likewise.
        (ia64_attribute_table): Add "model" attribute.
        (TARGET_ENCODE_SECTION_INFO): Define.
        (small_addr_symbolic_operand): New function.
        (got_symbolic_operand): Return 0 for a symbolref to an object
        in the small address area.
        (enum ia64_addr_area): New type.
        (small_ident1): New variable.
        (small_ident2): Likewise.
        (init_idents): New function.
        (ia64_get_addr_area): Likewise.
        (ia64_encode_addr_area): Likewise.
        (ia64_encode_section_info): Likewise.
        (ia64_expand_load_address): For symbolic references to objects in
        the small-address-area, load the address via gen_rtx_SET() (which,
        eventually, will expand into "addl").

From-SVN: r70209
parent 333384df
2003-08-06 David Mosberger <davidm@hpl.hp.com>
* doc/extend.texi (Function Attributes): Document the IA-64 version
of the "model" attribute.
* config/ia64/ia64.h (SYMBOL_FLAG_SMALL_ADDR): New macro.
(SYMBOL_REF_SMALL_ADDR_P): Ditto.
(PREDICATE_CODES): Mention "small_addr_symbolic_operand".
* config/ia64/ia64.c (ia64_handle_model_attribute): New function.
(ia64_encode_section_info): Likewise.
(ia64_attribute_table): Add "model" attribute.
(TARGET_ENCODE_SECTION_INFO): Define.
(small_addr_symbolic_operand): New function.
(got_symbolic_operand): Return 0 for a symbolref to an object
in the small address area.
(enum ia64_addr_area): New type.
(small_ident1): New variable.
(small_ident2): Likewise.
(init_idents): New function.
(ia64_get_addr_area): Likewise.
(ia64_encode_addr_area): Likewise.
(ia64_encode_section_info): Likewise.
(ia64_expand_load_address): For symbolic references to objects in
the small-address-area, load the address via gen_rtx_SET() (which,
eventually, will expand into "addl").
2003-08-06 Per Bothner <pbothner@apple.com> 2003-08-06 Per Bothner <pbothner@apple.com>
* line-map.h (fileline): New typedef. * line-map.h (fileline): New typedef.
......
...@@ -262,13 +262,17 @@ static void ia64_hpux_add_extern_decl PARAMS ((const char *name)) ...@@ -262,13 +262,17 @@ static void ia64_hpux_add_extern_decl PARAMS ((const char *name))
static void ia64_hpux_file_end PARAMS ((void)) static void ia64_hpux_file_end PARAMS ((void))
ATTRIBUTE_UNUSED; ATTRIBUTE_UNUSED;
static tree ia64_handle_model_attribute (tree *, tree, tree, int, bool *);
static void ia64_encode_section_info (tree, rtx, int);
/* Table of valid machine attributes. */ /* Table of valid machine attributes. */
static const struct attribute_spec ia64_attribute_table[] = static const struct attribute_spec ia64_attribute_table[] =
{ {
/* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */ /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
{ "syscall_linkage", 0, 0, false, true, true, NULL }, { "syscall_linkage", 0, 0, false, true, true, NULL },
{ NULL, 0, 0, false, false, false, NULL } { "model", 1, 1, true, false, false, ia64_handle_model_attribute },
{ NULL, 0, 0, false, false, false, NULL }
}; };
/* Initialize the GCC target structure. */ /* Initialize the GCC target structure. */
...@@ -368,6 +372,9 @@ static const struct attribute_spec ia64_attribute_table[] = ...@@ -368,6 +372,9 @@ static const struct attribute_spec ia64_attribute_table[] =
#undef TARGET_MACHINE_DEPENDENT_REORG #undef TARGET_MACHINE_DEPENDENT_REORG
#define TARGET_MACHINE_DEPENDENT_REORG ia64_reorg #define TARGET_MACHINE_DEPENDENT_REORG ia64_reorg
#undef TARGET_ENCODE_SECTION_INFO
#define TARGET_ENCODE_SECTION_INFO ia64_encode_section_info
struct gcc_target targetm = TARGET_INITIALIZER; struct gcc_target targetm = TARGET_INITIALIZER;
/* Return 1 if OP is a valid operand for the MEM of a CALL insn. */ /* Return 1 if OP is a valid operand for the MEM of a CALL insn. */
...@@ -413,6 +420,12 @@ sdata_symbolic_operand (op, mode) ...@@ -413,6 +420,12 @@ sdata_symbolic_operand (op, mode)
return 0; return 0;
} }
int
small_addr_symbolic_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
return SYMBOL_REF_SMALL_ADDR_P (op);
}
/* Return 1 if OP refers to a symbol, and is appropriate for a GOT load. */ /* Return 1 if OP refers to a symbol, and is appropriate for a GOT load. */
int int
...@@ -449,6 +462,8 @@ got_symbolic_operand (op, mode) ...@@ -449,6 +462,8 @@ got_symbolic_operand (op, mode)
return (INTVAL (op) & 0x3fff) == 0; return (INTVAL (op) & 0x3fff) == 0;
case SYMBOL_REF: case SYMBOL_REF:
if (SYMBOL_REF_SMALL_ADDR_P (op))
return 0;
case LABEL_REF: case LABEL_REF:
return 1; return 1;
...@@ -1040,6 +1055,129 @@ basereg_operand (op, mode) ...@@ -1040,6 +1055,129 @@ basereg_operand (op, mode)
REG_POINTER ((GET_CODE (op) == SUBREG) ? SUBREG_REG (op) : op)); REG_POINTER ((GET_CODE (op) == SUBREG) ? SUBREG_REG (op) : op));
} }
typedef enum
{
ADDR_AREA_NORMAL, /* normal address area */
ADDR_AREA_SMALL /* addressable by "addl" (-2MB < addr < 2MB) */
}
ia64_addr_area;
static GTY(()) tree small_ident1;
static GTY(()) tree small_ident2;
static void
init_idents (void)
{
if (small_ident1 == 0)
{
small_ident1 = get_identifier ("small");
small_ident2 = get_identifier ("__small__");
}
}
/* Retrieve the address area that has been chosen for the given decl. */
static ia64_addr_area
ia64_get_addr_area (tree decl)
{
tree model_attr;
model_attr = lookup_attribute ("model", DECL_ATTRIBUTES (decl));
if (model_attr)
{
tree id;
init_idents ();
id = TREE_VALUE (TREE_VALUE (model_attr));
if (id == small_ident1 || id == small_ident2)
return ADDR_AREA_SMALL;
}
return ADDR_AREA_NORMAL;
}
static tree
ia64_handle_model_attribute (tree *node, tree name,
tree args,
int flags ATTRIBUTE_UNUSED,
bool *no_add_attrs)
{
ia64_addr_area addr_area = ADDR_AREA_NORMAL;
ia64_addr_area area;
tree arg, decl = *node;
init_idents ();
arg = TREE_VALUE (args);
if (arg == small_ident1 || arg == small_ident2)
{
addr_area = ADDR_AREA_SMALL;
}
else
{
warning ("invalid argument of `%s' attribute",
IDENTIFIER_POINTER (name));
*no_add_attrs = true;
}
switch (TREE_CODE (decl))
{
case VAR_DECL:
if ((DECL_CONTEXT (decl) && TREE_CODE (DECL_CONTEXT (decl))
== FUNCTION_DECL)
&& !TREE_STATIC (decl))
{
error ("%Ha an address area attribute cannot be specified for "
"local variables", &DECL_SOURCE_LOCATION (decl), decl);
*no_add_attrs = true;
}
area = ia64_get_addr_area (decl);
if (area != ADDR_AREA_NORMAL && addr_area != area)
{
error ("%Ha address area of '%s' conflicts with previous "
"declaration", &DECL_SOURCE_LOCATION (decl), decl);
*no_add_attrs = true;
}
break;
case FUNCTION_DECL:
error ("%Ha address area attribute cannot be specified for functions",
&DECL_SOURCE_LOCATION (decl), decl);
*no_add_attrs = true;
break;
default:
warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
*no_add_attrs = true;
break;
}
return NULL_TREE;
}
static void
ia64_encode_addr_area (tree decl, rtx symbol)
{
int flags;
flags = SYMBOL_REF_FLAGS (symbol);
switch (ia64_get_addr_area (decl))
{
case ADDR_AREA_NORMAL: break;
case ADDR_AREA_SMALL: flags |= SYMBOL_FLAG_SMALL_ADDR; break;
default: abort ();
}
SYMBOL_REF_FLAGS (symbol) = flags;
}
static void
ia64_encode_section_info (tree decl, rtx rtl, int first)
{
default_encode_section_info (decl, rtl, first);
if (TREE_CODE (decl) == VAR_DECL
&& (TREE_STATIC (decl) || DECL_EXTERNAL (decl)))
ia64_encode_addr_area (decl, XEXP (rtl, 0));
}
/* Return 1 if the operands of a move are ok. */ /* Return 1 if the operands of a move are ok. */
int int
...@@ -1114,7 +1252,12 @@ ia64_expand_load_address (dest, src) ...@@ -1114,7 +1252,12 @@ ia64_expand_load_address (dest, src)
if (GET_MODE (dest) != Pmode) if (GET_MODE (dest) != Pmode)
dest = gen_rtx_REG (Pmode, REGNO (dest)); dest = gen_rtx_REG (Pmode, REGNO (dest));
if (TARGET_AUTO_PIC) if (GET_CODE (src) == SYMBOL_REF && SYMBOL_REF_SMALL_ADDR_P (src))
{
emit_insn (gen_rtx_SET (VOIDmode, dest, src));
return;
}
else if (TARGET_AUTO_PIC)
{ {
emit_insn (gen_load_gprel64 (dest, src)); emit_insn (gen_load_gprel64 (dest, src));
return; return;
......
...@@ -1098,11 +1098,15 @@ enum reg_class ...@@ -1098,11 +1098,15 @@ enum reg_class
(GET_CODE (VALUE) == MEM \ (GET_CODE (VALUE) == MEM \
&& GET_RTX_CLASS (GET_CODE (XEXP ((VALUE), 0))) != 'a' \ && GET_RTX_CLASS (GET_CODE (XEXP ((VALUE), 0))) != 'a' \
&& (reload_in_progress || memory_operand ((VALUE), VOIDmode))) && (reload_in_progress || memory_operand ((VALUE), VOIDmode)))
/* Symbol ref to small-address-area: */
#define CONSTRAINT_OK_FOR_T(VALUE) \
(GET_CODE (VALUE) == SYMBOL_REF && SYMBOL_REF_SMALL_ADDR_P (VALUE))
#define EXTRA_CONSTRAINT(VALUE, C) \ #define EXTRA_CONSTRAINT(VALUE, C) \
((C) == 'Q' ? CONSTRAINT_OK_FOR_Q (VALUE) \ ((C) == 'Q' ? CONSTRAINT_OK_FOR_Q (VALUE) \
: (C) == 'R' ? CONSTRAINT_OK_FOR_R (VALUE) \ : (C) == 'R' ? CONSTRAINT_OK_FOR_R (VALUE) \
: (C) == 'S' ? CONSTRAINT_OK_FOR_S (VALUE) \ : (C) == 'S' ? CONSTRAINT_OK_FOR_S (VALUE) \
: (C) == 'T' ? CONSTRAINT_OK_FOR_T (VALUE) \
: 0) : 0)
/* Basic Stack Layout */ /* Basic Stack Layout */
...@@ -2172,6 +2176,12 @@ do { \ ...@@ -2172,6 +2176,12 @@ do { \
/* Miscellaneous Parameters. */ /* Miscellaneous Parameters. */
/* Flag to mark data that is in the small address area (addressable
via "addl", that is, within a 2MByte offset of 0. */
#define SYMBOL_FLAG_SMALL_ADDR (SYMBOL_FLAG_MACH_DEP << 0)
#define SYMBOL_REF_SMALL_ADDR_P(X) \
((SYMBOL_REF_FLAGS (X) & SYMBOL_FLAG_SMALL_ADDR) != 0)
/* Define this if you have defined special-purpose predicates in the file /* Define this if you have defined special-purpose predicates in the file
`MACHINE.c'. For each predicate, list all rtl codes that can be in `MACHINE.c'. For each predicate, list all rtl codes that can be in
expressions matched by the predicate. */ expressions matched by the predicate. */
...@@ -2180,6 +2190,7 @@ do { \ ...@@ -2180,6 +2190,7 @@ do { \
{ "call_operand", {SUBREG, REG, SYMBOL_REF}}, \ { "call_operand", {SUBREG, REG, SYMBOL_REF}}, \
{ "got_symbolic_operand", {SYMBOL_REF, CONST, LABEL_REF}}, \ { "got_symbolic_operand", {SYMBOL_REF, CONST, LABEL_REF}}, \
{ "sdata_symbolic_operand", {SYMBOL_REF, CONST}}, \ { "sdata_symbolic_operand", {SYMBOL_REF, CONST}}, \
{ "small_addr_symbolic_operand", {SYMBOL_REF}}, \
{ "symbolic_operand", {SYMBOL_REF, CONST, LABEL_REF}}, \ { "symbolic_operand", {SYMBOL_REF, CONST, LABEL_REF}}, \
{ "function_operand", {SYMBOL_REF}}, \ { "function_operand", {SYMBOL_REF}}, \
{ "setjmp_operand", {SYMBOL_REF}}, \ { "setjmp_operand", {SYMBOL_REF}}, \
......
...@@ -325,7 +325,7 @@ ...@@ -325,7 +325,7 @@
[(set (match_operand:DI 0 "destination_operand" [(set (match_operand:DI 0 "destination_operand"
"=r,r,r,r, m, r,*f,*f,*f, Q, r,*b, r,*e, r,*d, r,*c") "=r,r,r,r, m, r,*f,*f,*f, Q, r,*b, r,*e, r,*d, r,*c")
(match_operand:DI 1 "move_operand" (match_operand:DI 1 "move_operand"
"rO,J,i,m,rO,*f,rO,*f, Q,*f,*b,rO,*e,rK,*d,rK,*c,rO"))] "rO,JT,i,m,rO,*f,rO,*f, Q,*f,*b,rO,*e,rK,*d,rK,*c,rO"))]
"ia64_move_ok (operands[0], operands[1])" "ia64_move_ok (operands[0], operands[1])"
{ {
static const char * const alt[] = { static const char * const alt[] = {
......
...@@ -2540,10 +2540,12 @@ the compiler. It is up to the programmer to provide these sequences. ...@@ -2540,10 +2540,12 @@ the compiler. It is up to the programmer to provide these sequences.
@item model (@var{model-name}) @item model (@var{model-name})
@cindex function addressability on the M32R/D @cindex function addressability on the M32R/D
Use this attribute on the M32R/D to set the addressability of an object, @cindex variable addressability on the IA-64
and of the code generated for a function.
The identifier @var{model-name} is one of @code{small}, @code{medium}, On the M32R/D, use this attribute to set the addressability of an
or @code{large}, representing each of the code models. object, and of the code generated for a function. The identifier
@var{model-name} is one of @code{small}, @code{medium}, or
@code{large}, representing each of the code models.
Small model objects live in the lower 16MB of memory (so that their Small model objects live in the lower 16MB of memory (so that their
addresses can be loaded with the @code{ld24} instruction), and are addresses can be loaded with the @code{ld24} instruction), and are
...@@ -2558,6 +2560,14 @@ compiler will generate @code{seth/add3} instructions to load their addresses), ...@@ -2558,6 +2560,14 @@ compiler will generate @code{seth/add3} instructions to load their addresses),
and may not be reachable with the @code{bl} instruction (the compiler will and may not be reachable with the @code{bl} instruction (the compiler will
generate the much slower @code{seth/add3/jl} instruction sequence). generate the much slower @code{seth/add3/jl} instruction sequence).
On IA-64, use this attribute to set the addressability of an object.
At present, the only supported identifier for @var{model-name} is
@code{small}, indicating addressability via ``small'' (22-bit)
addresses (so that their addresses can be loaded with the @code{addl}
instruction). Caveat: such addressing is by definition not position
independent and hence this attribute must not be used for objects
defined by shared libraries.
@item far @item far
@cindex functions which handle memory bank switching @cindex functions which handle memory bank switching
On 68HC11 and 68HC12 the @code{far} attribute causes the compiler to On 68HC11 and 68HC12 the @code{far} attribute causes the compiler to
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment