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").
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@70209
138bc75d-0d04-0410-961f-
82ee72b054a4
+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>
* line-map.h (fileline): New typedef.
static void ia64_hpux_file_end PARAMS ((void))
ATTRIBUTE_UNUSED;
+static tree ia64_handle_model_attribute (tree *, tree, tree, int, bool *);
+static void ia64_encode_section_info (tree, rtx, int);
+
\f
/* Table of valid machine attributes. */
static const struct attribute_spec ia64_attribute_table[] =
{
/* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
{ "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. */
#undef TARGET_MACHINE_DEPENDENT_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;
\f
/* Return 1 if OP is a valid operand for the MEM of a CALL insn. */
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. */
int
return (INTVAL (op) & 0x3fff) == 0;
case SYMBOL_REF:
+ if (SYMBOL_REF_SMALL_ADDR_P (op))
+ return 0;
case LABEL_REF:
return 1;
REG_POINTER ((GET_CODE (op) == SUBREG) ? SUBREG_REG (op) : op));
}
\f
+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));
+}
+\f
/* Return 1 if the operands of a move are ok. */
int
if (GET_MODE (dest) != Pmode)
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));
return;
(GET_CODE (VALUE) == MEM \
&& GET_RTX_CLASS (GET_CODE (XEXP ((VALUE), 0))) != 'a' \
&& (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) \
((C) == 'Q' ? CONSTRAINT_OK_FOR_Q (VALUE) \
: (C) == 'R' ? CONSTRAINT_OK_FOR_R (VALUE) \
: (C) == 'S' ? CONSTRAINT_OK_FOR_S (VALUE) \
+ : (C) == 'T' ? CONSTRAINT_OK_FOR_T (VALUE) \
: 0)
\f
/* Basic Stack Layout */
\f
/* 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
`MACHINE.c'. For each predicate, list all rtl codes that can be in
expressions matched by the predicate. */
{ "call_operand", {SUBREG, REG, SYMBOL_REF}}, \
{ "got_symbolic_operand", {SYMBOL_REF, CONST, LABEL_REF}}, \
{ "sdata_symbolic_operand", {SYMBOL_REF, CONST}}, \
+{ "small_addr_symbolic_operand", {SYMBOL_REF}}, \
{ "symbolic_operand", {SYMBOL_REF, CONST, LABEL_REF}}, \
{ "function_operand", {SYMBOL_REF}}, \
{ "setjmp_operand", {SYMBOL_REF}}, \
[(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")
(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])"
{
static const char * const alt[] = {
@item model (@var{model-name})
@cindex function addressability on the M32R/D
-Use this attribute on the M32R/D to set the addressability of an 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.
+@cindex variable addressability on the IA-64
+
+On the M32R/D, use this attribute to set the addressability of an
+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
addresses can be loaded with the @code{ld24} instruction), and are
and may not be reachable with the @code{bl} instruction (the compiler will
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
@cindex functions which handle memory bank switching
On 68HC11 and 68HC12 the @code{far} attribute causes the compiler to