ia64.c (got_symbolic_operand): New.
authorRichard Henderson <rth@gcc.gnu.org>
Mon, 10 Jul 2000 20:51:23 +0000 (13:51 -0700)
committerRichard Henderson <rth@gcc.gnu.org>
Mon, 10 Jul 2000 20:51:23 +0000 (13:51 -0700)
        * config/ia64/ia64.c (got_symbolic_operand): New.
        (symbolic_operand, move_operand): Revert 0701 change.
        * config/ia64/ia64.h (PREDICATE_CODES): Update.
        * config/ia64/ia64-protos.h (got_symbolic_operand): Declare.
        * config/ia64/ia64.md (movdi): Revert 0701 wrt symbolic_operand;
        split the offset into a 14-bit low part instead of a 13-bit low part.
        (load_fptr): Mark the mem as unchanging.
        (load_symptr): Use got_symbolic_operand.

From-SVN: r34948

gcc/ChangeLog
gcc/config/ia64/ia64-protos.h
gcc/config/ia64/ia64.c
gcc/config/ia64/ia64.h
gcc/config/ia64/ia64.md

index 232e831..1207b5c 100644 (file)
@@ -1,3 +1,14 @@
+2000-07-10  Richard Henderson  <rth@cygnus.com>
+
+       * config/ia64/ia64.c (got_symbolic_operand): New.
+       (symbolic_operand, move_operand): Revert 0701 change.
+       * config/ia64/ia64.h (PREDICATE_CODES): Update.
+       * config/ia64/ia64-protos.h (got_symbolic_operand): Declare.
+       * config/ia64/ia64.md (movdi): Revert 0701 wrt symbolic_operand;
+       split the offset into a 14-bit low part instead of a 13-bit low part.
+       (load_fptr): Mark the mem as unchanging.
+       (load_symptr): Use got_symbolic_operand.
+
 2000-07-10  Nick Clifton  <nickc@cygnus.com>
 
        * libgcc2.c (next_stack_level): Cast result of computation to
 
 2000-07-08  Richard Henderson  <rth@cygnus.com>
 
-        * final.c (final): Do not abort when reg-stack introduces
+       * final.c (final): Do not abort when reg-stack introduces
        a new insn.
 
 2000-07-08  Zack Weinberg  <zack@wolery.cumb.org>
@@ -475,13 +486,13 @@ Mon Jul  3 21:31:43 2000  Clinton Popetz  <cpopetz@cygnus.com>
        check_macro_redefinition, save_expansion): New.
 
        * cpplex.c (skip_block_comment, skip_line_comment, parse_name,
-        parse_string, output_line_command, trigraph_replace,
-        lex_line, cpp_push_buffer, cpp_pop_buffer, cpp_output_tokens,
-        cpp_scan_buffer_nooutput, cpp_scan_buffer, cpp_free_toklist,
-        cpp_idcmp, _cpp_get_directive_token, _cpp_init_input_buffer,
+       parse_string, output_line_command, trigraph_replace,
+       lex_line, cpp_push_buffer, cpp_pop_buffer, cpp_output_tokens,
+       cpp_scan_buffer_nooutput, cpp_scan_buffer, cpp_free_toklist,
+       cpp_idcmp, _cpp_get_directive_token, _cpp_init_input_buffer,
        _cpp_skip_rest_of_line): Modify.
 
-        (maybe_macroexpand, skip_comment, copy_comment, skip_string,
+       (maybe_macroexpand, skip_comment, copy_comment, skip_string,
        find_position, null_warning, bump_column, expand_name_space,
        pedantic_whitespace, _cpp_output_list, _cpp_slice_toklist,
        _cpp_squeeze_toklist, _cpp_scan_until, _cpp_skip_hspace,
@@ -489,19 +500,19 @@ Mon Jul  3 21:31:43 2000  Clinton Popetz  <cpopetz@cygnus.com>
        _cpp_prescan): Delete.
 
        (dump_param_spelling, process_directive, lex_next,
-        is_macro_disabled, stringify_arg, expand_context_stack,
-        output_token, make_string_token, alloc_number_token,
-        special_symbol, duplicate_token, maybe_paste_with_next,
-        can_paste, prevent_macro_expansion, restore_macro_expansion,
-        get_temp_token, release_temp_tokens, quote_string,
-        token_names, token_spellings, _cpp_expand_name_space,
-        _cpp_glue_header_name, _cpp_reserve_name_space,
-        digraph_spellings, trigraph_ok, skip_whitespace, save_comment,
-        placemarker_token, eof_token, cpp_context, macro_args,
-        get_raw_token, parse_arg, parse_args, save_token,
-        push_arg_context, push_macro_context, pop_context,
-        do_pop_context, free_macro_args, _cpp_get_line,
-        _cpp_run_directive): New.
+       is_macro_disabled, stringify_arg, expand_context_stack,
+       output_token, make_string_token, alloc_number_token,
+       special_symbol, duplicate_token, maybe_paste_with_next,
+       can_paste, prevent_macro_expansion, restore_macro_expansion,
+       get_temp_token, release_temp_tokens, quote_string,
+       token_names, token_spellings, _cpp_expand_name_space,
+       _cpp_glue_header_name, _cpp_reserve_name_space,
+       digraph_spellings, trigraph_ok, skip_whitespace, save_comment,
+       placemarker_token, eof_token, cpp_context, macro_args,
+       get_raw_token, parse_arg, parse_args, save_token,
+       push_arg_context, push_macro_context, pop_context,
+       do_pop_context, free_macro_args, _cpp_get_line,
+       _cpp_run_directive): New.
 
        * cpplib.c (validate_else, parse_include, push_conditional,
        pass_thru_directive, read_line_number, parse_ifdef,
@@ -777,8 +788,8 @@ Mon Jul  3 00:32:47 2000  Jeffrey A Law  (law@cygnus.com)
 
 2000-06-30  Catherine Moore  <clm@cygnus.com>
  
-        * c-common.c (decl_attributes):  Differentiate between
-        types and type decls for alignment.
+       * c-common.c (decl_attributes):  Differentiate between
+       types and type decls for alignment.
 
 2000-06-30  Nathan Sidwell  <nathan@codesourcery.com>
 
@@ -860,8 +871,8 @@ Mon Jul  3 00:32:47 2000  Jeffrey A Law  (law@cygnus.com)
 
 2000-06-29  Andrew Haley  <aph@cygnus.com>
 
-        * config/ia64/linux.h (JMP_BUF_SIZE): Size is in Pmode units, not
-        bytes: remove the multiply by 8.
+       * config/ia64/linux.h (JMP_BUF_SIZE): Size is in Pmode units, not
+       bytes: remove the multiply by 8.
 
 2000-06-29  Philipp Thomas  <pthomas@suse.de>
 
index dcfe8cc..af3e5d7 100644 (file)
@@ -29,6 +29,7 @@ extern rtx ia64_compare_op0, ia64_compare_op1;
 #ifdef RTX_CODE
 extern int call_operand PARAMS((rtx, enum machine_mode));
 extern int sdata_symbolic_operand PARAMS((rtx, enum machine_mode));
+extern int got_symbolic_operand PARAMS((rtx, enum machine_mode));
 extern int symbolic_operand PARAMS((rtx, enum machine_mode));
 extern int function_operand PARAMS((rtx, enum machine_mode));
 extern int setjmp_operand PARAMS((rtx, enum machine_mode));
index 1b0e0c3..3628cb4 100644 (file)
@@ -176,10 +176,10 @@ sdata_symbolic_operand (op, mode)
   return 0;
 }
 
-/* Return 1 if OP refers to a symbol.  */
+/* Return 1 if OP refers to a symbol, and is appropriate for a GOT load.  */
 
 int
-symbolic_operand (op, mode)
+got_symbolic_operand (op, mode)
      rtx op;
      enum machine_mode mode ATTRIBUTE_UNUSED;
 {
@@ -194,12 +194,43 @@ symbolic_operand (op, mode)
       op = XEXP (op, 1);
       if (GET_CODE (op) != CONST_INT)
        return 0;
-      /* Force the low 13 bits of the constant to zero so that we do not
+
+       return 1;
+
+      /* Ok if we're not using GOT entries at all.  */
+      if (TARGET_NO_PIC || TARGET_AUTO_PIC)
+       return 1;
+
+      /* "Ok" while emitting rtl, since otherwise we won't be provided
+        with the entire offset during emission, which makes it very
+        hard to split the offset into high and low parts.  */
+      if (rtx_equal_function_value_matters)
+       return 1;
+
+      /* Force the low 14 bits of the constant to zero so that we do not
         use up so many GOT entries.  */
-      if (! TARGET_NO_PIC && ! TARGET_AUTO_PIC && (INTVAL (op) & 0x1fff) != 0)
-       return 0;
+      return (INTVAL (op) & 0x3fff) == 0;
+
+    case SYMBOL_REF:
+    case LABEL_REF:
       return 1;
 
+    default:
+      break;
+    }
+  return 0;
+}
+
+/* Return 1 if OP refers to a symbol.  */
+
+int
+symbolic_operand (op, mode)
+     rtx op;
+     enum machine_mode mode ATTRIBUTE_UNUSED;
+{
+  switch (GET_CODE (op))
+    {
+    case CONST:
     case SYMBOL_REF:
     case LABEL_REF:
       return 1;
@@ -284,10 +315,7 @@ move_operand (op, mode)
      rtx op;
      enum machine_mode mode;
 {
-  if (! TARGET_NO_PIC
-      && (GET_CODE (op) == CONST
-         || GET_CODE (op) == SYMBOL_REF
-         || GET_CODE (op) == LABEL_REF))
+  if (! TARGET_NO_PIC && symbolic_operand (op, mode))
     return 0;
 
   return general_operand (op, mode);
index 9db1675..be94fc0 100644 (file)
@@ -2705,6 +2705,7 @@ do {                                                                      \
 
 #define PREDICATE_CODES \
 { "call_operand", {SUBREG, REG, SYMBOL_REF}},                          \
+{ "got_symbolic_operand", {SYMBOL_REF, CONST, LABEL_REF}},             \
 { "sdata_symbolic_operand", {SYMBOL_REF, CONST}},                      \
 { "symbolic_operand", {SYMBOL_REF, CONST, LABEL_REF}},                 \
 { "function_operand", {SYMBOL_REF}},                                   \
index c6bfb9f..bab7b90 100644 (file)
 {
   /* ??? Should generalize this, so that we can also support 32 bit
      pointers.  */
-  if (! TARGET_NO_PIC
-      && (GET_CODE (operands[1]) == CONST
-         || GET_CODE (operands[1]) == SYMBOL_REF
-         || GET_CODE (operands[1]) == LABEL_REF))
+  if (! TARGET_NO_PIC && symbolic_operand (operands[1], DImode))
     {
       rtx temp;
 
               && GET_CODE (XEXP (XEXP (operands[1], 0), 1)) == CONST_INT
               && (INTVAL (XEXP (XEXP (operands[1], 0), 1)) & 0x1fff) != 0)
        {
-         HOST_WIDE_INT ofs = INTVAL (XEXP (XEXP (operands[1], 0), 1));
-         rtx sym = XEXP (XEXP (operands[1], 0), 0);
          rtx subtarget = no_new_pseudos ? temp : gen_reg_rtx (DImode);
-
-         sym = plus_constant (sym, ofs & ~(HOST_WIDE_INT)0x1fff);
-         ofs &= 0x1fff;
-
-         emit_insn (gen_load_symptr (subtarget, sym));
-         emit_insn (gen_adddi3 (temp, subtarget, GEN_INT (ofs)));
+         rtx sym = XEXP (XEXP (operands[1], 0), 0);
+         HOST_WIDE_INT ofs, hi, lo;
+
+         /* Split the offset into a sign extended 14-bit low part
+            and a complementary high part.  */
+         ofs = INTVAL (XEXP (XEXP (operands[1], 0), 1));
+         lo = ((ofs & 0x3fff) ^ 0x2000) - 0x2000;
+         hi = ofs - lo;
+       
+         emit_insn (gen_load_symptr (subtarget, plus_constant (sym, hi)));
+         emit_insn (gen_adddi3 (temp, subtarget, GEN_INT (lo)));
        }
       else
        emit_insn (gen_load_symptr (temp, operands[1]));
 (define_expand "load_fptr"
   [(set (match_dup 2)
        (plus:DI (reg:DI 1) (match_operand:DI 1 "function_operand" "")))
-   (set (match_operand:DI 0 "register_operand" "") (mem:DI (match_dup 2)))]
+   (set (match_operand:DI 0 "register_operand" "") (match_dup 3))]
   ""
   "
 {
-  if (reload_in_progress)
-    operands[2] = operands[0];
-  else
-    operands[2] = gen_reg_rtx (DImode);
+  operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
+  operands[3] = gen_rtx_MEM (DImode, operands[2]);
+  RTX_UNCHANGING_P (operands[3]) = 1;
 }")
 
 (define_insn "*load_fptr_internal1"
    (set (match_operand:DI 0 "register_operand" "")
        (plus:DI (reg:DI 1) (match_dup 2)))]
   ""
-  "{
-  if (reload_in_progress)
-    operands[2] = operands[0];
-  else
-    operands[2] = gen_reg_rtx (DImode);
+  "
+{
+  operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
 }")
 
 (define_expand "load_symptr"
   [(set (match_dup 2)
-       (plus:DI (reg:DI 1) (match_operand:DI 1 "symbolic_operand" "")))
+       (plus:DI (reg:DI 1) (match_operand:DI 1 "got_symbolic_operand" "")))
    (set (match_operand:DI 0 "register_operand" "") (match_dup 3))]
   ""
   "
 {
-  operands[2] = reload_in_progress ? operands[0] : gen_reg_rtx (DImode);
+  operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
   operands[3] = gen_rtx_MEM (DImode, operands[2]);
   RTX_UNCHANGING_P (operands[3]) = 1;
 }")
 
 (define_insn "*load_symptr_internal1"
   [(set (match_operand:DI 0 "register_operand" "=r")
-       (plus:DI (reg:DI 1) (match_operand:DI 1 "symbolic_operand" "s")))]
+       (plus:DI (reg:DI 1) (match_operand:DI 1 "got_symbolic_operand" "s")))]
   ""
   "addl %0 = @ltoff(%1), gp"
   [(set_attr "type" "A")])