From: Jim Wilson Date: Wed, 3 May 2000 18:46:05 +0000 (-0700) Subject: Patches from David Mosberger, and a patch to make bootstrap work. X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=59da9a7d5c232801fe1fb3d478b4c29120dcbdec;p=platform%2Fupstream%2Fgcc.git Patches from David Mosberger, and a patch to make bootstrap work. * config/ia64/ia64.c (ia64_encode_section_info): Add check for TREE_ASM_WRITTEN. * config/ia64/ia64.c (ia64_override_options): Force -mconstant-gp if -mauto-pic is on. ... From-SVN: r33638 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index eed7f65..c3559a4 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,37 @@ +Wed May 3 11:43:53 2000 Jim Wilson + + * config/ia64/ia64.c (ia64_encode_section_info): Add check for + TREE_ASM_WRITTEN. + +2000-05-03 David Mosberger + + * config/ia64/ia64.c (ia64_override_options): Force -mconstant-gp + if -mauto-pic is on. + (ia64_epilogue_uses): Mark "gp" (r1) as used by the epilogue if + -mconstant-gp is in effect and function-descriptors are being used + to make indirect calls. + * config/ia64/ia64.h (MASK_CONST_GP): New macro. + (MASK_AUTO_PIC): Ditto. + (TARGET_CONST_GP): Ditto. + (TARGET_AUTO_PIC): Ditto. + (TARGET_SWITCHES): Add -mconstant-gp and -mauto-pic options. + (ASM_OUTPUT_DOUBLE_INT): Don't generate @fptr() if -mauto-pic or + -mno-pic is in effect. + (ASM_OUTPUT_XDATA_DOUBLE_INT): Ditto. + * config/ia64/ia64.md (movdi): Use gen_load_gprel64() if + -mauto-pic is in effect. + (gprel64_offset): New pattern. + (load_gprel64): Ditto. + (call): Handle -mauto-pic like -mno-pic (don't use fptr). If + -mconstant-gp is in effect, no need to preserve gp around direct + calls. + (call_value): Ditto. + * config/ia64/linux.h (PROFILE_BEFORE_PROLOGUE): Define. + (FUNCTION_PROFILER): Define. + * config/ia64/sysv4.h (ASM_OUTPUT_CONSTRUCTOR): Don't generate + @fptr() directive when -mno-pic or -mauto-pic is in effect. + (ASM_OUTPUT_DESTRUCTOR): Ditto. + 2000-05-03 Richard Henderson * Makefile.in (STAGESTUFF): Add libgcc libgcc.mk. diff --git a/gcc/config/ia64/ia64.c b/gcc/config/ia64/ia64.c index f5af654..b334dc6 100644 --- a/gcc/config/ia64/ia64.c +++ b/gcc/config/ia64/ia64.c @@ -2057,6 +2057,9 @@ ia64_mark_machine_status (p) void ia64_override_options () { + if (TARGET_AUTO_PIC) + target_flags |= MASK_CONST_GP; + if (ia64_fixed_range_string) fix_range (ia64_fixed_range_string); @@ -2707,6 +2710,14 @@ int ia64_epilogue_uses (regno) int regno; { + /* When a function makes a call through a function descriptor, we + will write a (potentially) new value to "gp". After returning + from such a call, we need to make sure the function restores the + original gp-value, even if the function itself does not use the + gp anymore. */ + if (regno == R_GR(1) && TARGET_CONST_GP && !(TARGET_AUTO_PIC || TARGET_NO_PIC)) + return 1; + /* For functions defined with the syscall_linkage attribute, all input registers are marked as live at all function exits. This prevents the register allocator from using the input registers, which in turn makes it @@ -2812,6 +2823,14 @@ ia64_encode_section_info (decl) || ! strcmp (str, "__DTOR_END__")) ; + /* If the variable has already been defined in the output file, then it + is too late to put it in sdata if it wasn't put there in the first + place. The test is here rather than above, because if it is already + in sdata, then it can stay there. */ + + else if (TREE_ASM_WRITTEN (decl)) + ; + /* If this is an incomplete type with size 0, then we can't put it in sdata because it might be too big when completed. */ else if (size > 0 && size <= ia64_section_threshold diff --git a/gcc/config/ia64/ia64.h b/gcc/config/ia64/ia64.h index 163f983..e97ffef 100644 --- a/gcc/config/ia64/ia64.h +++ b/gcc/config/ia64/ia64.h @@ -66,6 +66,10 @@ extern int target_flags; #define MASK_NO_SDATA 0x00000080 /* Disable sdata/scommon/sbss. */ +#define MASK_CONST_GP 0x00000100 /* treat gp as program-wide constant */ + +#define MASK_AUTO_PIC 0x00000200 /* generate automatically PIC */ + #define MASK_DWARF2_ASM 0x40000000 /* test dwarf2 line info via gas. */ #define TARGET_BIG_ENDIAN (target_flags & MASK_BIG_ENDIAN) @@ -84,13 +88,17 @@ extern int target_flags; #define TARGET_NO_SDATA (target_flags & MASK_NO_SDATA) +#define TARGET_CONST_GP (target_flags & MASK_CONST_GP) + +#define TARGET_AUTO_PIC (target_flags & MASK_AUTO_PIC) + #define TARGET_DWARF2_ASM (target_flags & MASK_DWARF2_ASM) /* This macro defines names of command options to set and clear bits in `target_flags'. Its definition is an initializer with a subgrouping for each command option. */ -#define TARGET_SWITCHES \ +#define TARGET_SWITCHES \ { \ { "big-endian", MASK_BIG_ENDIAN, \ "Generate big endian code" }, \ @@ -118,6 +126,10 @@ extern int target_flags; "Disable use of sdata/scommon/sbss"}, \ { "sdata", -MASK_NO_SDATA, \ "Enable use of sdata/scommon/sbss"}, \ + { "constant-gp", MASK_CONST_GP, \ + "gp is constant (but save/restore gp on indirect calls)" }, \ + { "auto-pic", MASK_AUTO_PIC, \ + "Generate self-relocatable code" }, \ { "dwarf2-asm", MASK_DWARF2_ASM, \ "Enable Dwarf 2 line debug info via GNU as"}, \ { "no-dwarf2-asm", -MASK_DWARF2_ASM, \ @@ -2116,10 +2128,10 @@ do { \ #define ASM_OUTPUT_DOUBLE_INT(FILE, VALUE) \ do { \ fprintf (FILE, "\tdata8\t"); \ - if (SYMBOL_REF_FLAG (VALUE)) \ + if (!(TARGET_NO_PIC || TARGET_AUTO_PIC) && SYMBOL_REF_FLAG (VALUE)) \ fprintf (FILE, "@fptr("); \ output_addr_const (FILE, (VALUE)); \ - if (SYMBOL_REF_FLAG (VALUE)) \ + if (!(TARGET_NO_PIC || TARGET_AUTO_PIC) && SYMBOL_REF_FLAG (VALUE)) \ fprintf (FILE, ")"); \ fprintf (FILE, "\n"); \ } while (0) @@ -2161,16 +2173,16 @@ do { \ #define ASM_OUTPUT_XDATA_DOUBLE_INT(FILE, SECTION, VALUE) \ do { \ + int need_closing_paren = 0; \ fprintf (FILE, "\t.xdata8\t\"%s\", ", SECTION); \ - if (GET_CODE (VALUE) == SYMBOL_REF) \ + if (!(TARGET_NO_PIC || TARGET_AUTO_PIC) \ + && GET_CODE (VALUE) == SYMBOL_REF) \ { \ - if (SYMBOL_REF_FLAG (VALUE)) \ - fprintf (FILE, "@fptr("); \ - else \ - fprintf (FILE, "@segrel("); \ + fprintf (FILE, SYMBOL_REF_FLAG (VALUE) ? "@fptr(" : "@segrel("); \ + need_closing_paren = 1; \ } \ - output_addr_const (FILE, (VALUE)); \ - if (GET_CODE (VALUE) == SYMBOL_REF) \ + output_addr_const (FILE, VALUE); \ + if (need_closing_paren) \ fprintf (FILE, ")"); \ fprintf (FILE, "\n"); \ } while (0) diff --git a/gcc/config/ia64/ia64.md b/gcc/config/ia64/ia64.md index e9ef493e..6f243f8 100644 --- a/gcc/config/ia64/ia64.md +++ b/gcc/config/ia64/ia64.md @@ -229,7 +229,10 @@ else temp = operands[0]; - if (GET_CODE (operands[1]) == SYMBOL_REF && SYMBOL_REF_FLAG (operands[1])) + if (TARGET_AUTO_PIC) + emit_insn (gen_load_gprel64 (temp, operands[1])); + else if (GET_CODE (operands[1]) == SYMBOL_REF + && SYMBOL_REF_FLAG (operands[1])) emit_insn (gen_load_fptr (temp, operands[1])); else if (sdata_symbolic_operand (operands[1], DImode)) emit_insn (gen_load_gprel (temp, operands[1])); @@ -296,6 +299,26 @@ "addl %0 = @gprel(%1), gp" [(set_attr "type" "A")]) +(define_insn "gprel64_offset" + [(set (match_operand:DI 0 "register_operand" "=r") + (minus:DI (match_operand:DI 1 "symbolic_operand" "") (reg:DI 1)))] + "" + "movl %0 = @gprel(%1)" + [(set_attr "type" "L")]) + +(define_expand "load_gprel64" + [(set (match_dup 2) + (minus:DI (match_operand:DI 1 "symbolic_operand" "") (reg:DI 1))) + (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); +}") + (define_expand "load_symptr" [(set (match_dup 2) (plus:DI (reg:DI 1) (match_operand:DI 1 "symbolic_operand" ""))) @@ -2521,13 +2544,16 @@ rtx addr = XEXP (operands[0], 0); enum machine_mode mode = GET_MODE (addr); - if (TARGET_NO_PIC) + if (TARGET_NO_PIC || TARGET_AUTO_PIC) emit_call_insn (gen_call_internal (addr, operands[1], gen_rtx_REG (DImode, R_BR (0)))); /* If this is an indirect call, then we have the address of a descriptor. */ else if (! symbolic_operand (addr, mode)) emit_insn (gen_indirect_call_pic (addr, operands[1])); + else if (TARGET_CONST_GP) + emit_call_insn (gen_call_internal (addr, operands[1], + gen_rtx_REG (DImode, R_BR (0)))); /* ??? This is an unsatisfying solution. Should rethink. */ else if (setjmp_operand (addr, mode)) emit_insn (gen_setjmp_call_pic (addr, operands[1])); @@ -2631,7 +2657,7 @@ rtx addr = XEXP (operands[1], 0); enum machine_mode mode = GET_MODE (addr); - if (TARGET_NO_PIC) + if (TARGET_NO_PIC || TARGET_AUTO_PIC) emit_call_insn (gen_call_value_internal (operands[0], addr, operands[2], gen_rtx_REG (DImode, R_BR (0)))); @@ -2646,6 +2672,9 @@ emit_insn (gen_indirect_call_value_pic (operands[0], addr, operands[2])); } + else if (TARGET_CONST_GP) + emit_call_insn (gen_call_value_internal (operands[0], addr, operands[2], + gen_rtx_REG (DImode, R_BR (0)))); /* ??? This is an unsatisfying solution. Should rethink. */ else if (setjmp_operand (addr, mode)) emit_insn (gen_setjmp_call_value_pic (operands[0], addr, operands[2])); diff --git a/gcc/config/ia64/linux.h b/gcc/config/ia64/linux.h index 62fc1a7..5108cfa 100644 --- a/gcc/config/ia64/linux.h +++ b/gcc/config/ia64/linux.h @@ -26,4 +26,33 @@ #define DONT_USE_BUILTIN_SETJMP #define JMP_BUF_SIZE (8 * 76) + +/* Output any profiling code before the prologue. */ + +#undef PROFILE_BEFORE_PROLOGUE +#define PROFILE_BEFORE_PROLOGUE 1 + +/* A C statement or compound statement to output to FILE some assembler code to + call the profiling subroutine `mcount'. */ + +#undef FUNCTION_PROFILER +#define FUNCTION_PROFILER(FILE, LABELNO) \ +do { \ + char buf[20]; \ + ASM_GENERATE_INTERNAL_LABEL (buf, "LP", LABELNO); \ + fputs ("\talloc out0 = ar.pfs, 8, 0, 4, 0\n", FILE); \ + if (TARGET_AUTO_PIC) \ + fputs ("\tmovl out3 = @gprel(", FILE); \ + else \ + fputs ("\taddl out3 = @ltoff(", FILE); \ + assemble_name (FILE, buf); \ + if (TARGET_AUTO_PIC) \ + fputs (");;\n", FILE); \ + else \ + fputs ("), r1;;\n", FILE); \ + fputs ("\tmov out1 = r1\n", FILE); \ + fputs ("\tmov out2 = b0\n", FILE); \ + fputs ("\tbr.call.sptk.many b0 = _mcount;;\n", FILE); \ +} while (0) + /* End of linux.h */ diff --git a/gcc/config/ia64/sysv4.h b/gcc/config/ia64/sysv4.h index 95f73a3..7e9e2c9 100644 --- a/gcc/config/ia64/sysv4.h +++ b/gcc/config/ia64/sysv4.h @@ -84,9 +84,15 @@ while (0) #define ASM_OUTPUT_CONSTRUCTOR(FILE,NAME) \ do { \ ctors_section (); \ - fputs ("\tdata8\t @fptr(", FILE); \ + if (TARGET_NO_PIC || TARGET_AUTO_PIC) \ + fputs ("\tdata8\t ", FILE); \ + else \ + fputs ("\tdata8\t @fptr(", FILE); \ assemble_name (FILE, NAME); \ - fputs (")\n", FILE); \ + if (TARGET_NO_PIC || TARGET_AUTO_PIC) \ + fputs ("\n", FILE); \ + else \ + fputs (")\n", FILE); \ } while (0) /* A C statement (sans semicolon) to output an element in the table of @@ -96,9 +102,15 @@ while (0) #define ASM_OUTPUT_DESTRUCTOR(FILE,NAME) \ do { \ dtors_section (); \ - fputs ("\tdata8\t @fptr(", FILE); \ + if (TARGET_NO_PIC || TARGET_AUTO_PIC) \ + fputs ("\tdata8\t ", FILE); \ + else \ + fputs ("\tdata8\t @fptr(", FILE); \ assemble_name (FILE, NAME); \ - fputs (")\n", FILE); \ + if (TARGET_NO_PIC || TARGET_AUTO_PIC) \ + fputs ("\n", FILE); \ + else \ + fputs (")\n", FILE); \ } while (0) /* svr4.h undefines this, so we need to define it here. */