From a32767e4522942ab7b582da2c60537e0c0034caa Mon Sep 17 00:00:00 2001 From: David Mosberger Date: Wed, 6 Aug 2003 21:08:29 +0000 Subject: [PATCH] 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 --- gcc/ChangeLog | 27 ++++++++ gcc/config/ia64/ia64.c | 147 +++++++++++++++++++++++++++++++++++++++- gcc/config/ia64/ia64.h | 11 +++ gcc/config/ia64/ia64.md | 2 +- gcc/doc/extend.texi | 18 +++-- 5 files changed, 198 insertions(+), 7 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b918929ccc3..afc2de1fbc9 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,30 @@ +2003-08-06 David Mosberger + + * 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 * line-map.h (fileline): New typedef. diff --git a/gcc/config/ia64/ia64.c b/gcc/config/ia64/ia64.c index b277eb0e2b0..f2e27d0105f 100644 --- a/gcc/config/ia64/ia64.c +++ b/gcc/config/ia64/ia64.c @@ -262,13 +262,17 @@ static void ia64_hpux_add_extern_decl PARAMS ((const char *name)) 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); + /* 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. */ @@ -368,6 +372,9 @@ static const struct attribute_spec ia64_attribute_table[] = #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; /* Return 1 if OP is a valid operand for the MEM of a CALL insn. */ @@ -413,6 +420,12 @@ sdata_symbolic_operand (op, mode) 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 @@ -449,6 +462,8 @@ got_symbolic_operand (op, mode) return (INTVAL (op) & 0x3fff) == 0; case SYMBOL_REF: + if (SYMBOL_REF_SMALL_ADDR_P (op)) + return 0; case LABEL_REF: return 1; @@ -1040,6 +1055,129 @@ basereg_operand (op, mode) 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. */ int @@ -1114,7 +1252,12 @@ ia64_expand_load_address (dest, src) 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; diff --git a/gcc/config/ia64/ia64.h b/gcc/config/ia64/ia64.h index e7e1d29d613..fe2c8038ebf 100644 --- a/gcc/config/ia64/ia64.h +++ b/gcc/config/ia64/ia64.h @@ -1098,11 +1098,15 @@ enum reg_class (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) /* Basic Stack Layout */ @@ -2172,6 +2176,12 @@ do { \ /* 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. */ @@ -2180,6 +2190,7 @@ do { \ { "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}}, \ diff --git a/gcc/config/ia64/ia64.md b/gcc/config/ia64/ia64.md index acf31c7e8f3..faff0ee5c55 100644 --- a/gcc/config/ia64/ia64.md +++ b/gcc/config/ia64/ia64.md @@ -325,7 +325,7 @@ [(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[] = { diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index 4ccc68b43e2..f9ac87e3f46 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -2540,10 +2540,12 @@ the compiler. It is up to the programmer to provide these sequences. @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 @@ -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 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 -- 2.30.2