summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorlaw <law@138bc75d-0d04-0410-961f-82ee72b054a4>1994-11-11 04:33:43 +0000
committerlaw <law@138bc75d-0d04-0410-961f-82ee72b054a4>1994-11-11 04:33:43 +0000
commitb4a7bf105484977d1fb83f89dbad7e47ea194fef (patch)
tree4d67fb8a4a81191e22da8cca8a7163d77653ba82 /gcc
parent2ed5782f394dd4dd0799a29c8727eaaa44ca7603 (diff)
downloadgcc-b4a7bf105484977d1fb83f89dbad7e47ea194fef.tar.gz
* PA PIC support.
* pa.c (secondary_reload_class): Refine. Readonly data needs a secondary reload only during PIC generation. Loading a floating point register with a constant requires a register from R1_REGS during -fPIC code generation. (read_only_operand): Constant pool entries are no longer read only during PIC code generation. (hppa_legitimize_address): If flag_pic is nonzero, then immediately call legitimize_pic_address. (emit_move_sequence): Call legitimize_pic_address to handle constant data. Handle secondary reloads for PIC. Use pic_label_operand rather than open coding the test. Handle loading a LABEL_REF when generating PIC. (legitimzie_pic_address): Handle constant data addressing for PIC here. Fix loading of symbolic addresses for -fPIC generation. (pic_label_operand): Renamed from pic_operand. Handle any read only operand (such as constant data). Reject function addresses, Accept SYMBOL_REF with the read-only bit set. Generalize to handle (const (plus (reg) (int))). (finalize_pic): Delete unused function. (check_pic): Delete function. (pic_pc_rtx): Delete variable definition. (current_function_uses_pic_offset_table): Delete extern decl. (force_reg, validize_mem): Likewise. (output_global_address): Don't tack on "-$global$" when generating PIC code. (finalize_pic): Don't emit code for initialization of hppa_save_pic_table_rtx here. Don't claim we USE pic_offset_table_rtx at function end. * pa.h (SELECT_RTX_SECTION): Define. During PIC generation everything (in the constant pool) goes into the data space. (PRINT_OPERAND_ADDRESS): Handle CONST_INTs during PIC generation. Handle LO_SUM address during -fPIC generation. (LEGITIMATE_CONSTANT_P): Reject function labels when generating PIC code. (GO_IF_LEGITIMATE_ADDRESS): Only accept pic_reg + SYMBOL_REF for -fpic. (EXTRA_SECTION_FUNCTIONS): For -fpic, use the TEXT section for constants to avoid GAS lossage. (OVERRIDE_OPTIONS): Delete. (PIC_OFFSET_TABLE_REG_CALL_CLOBBERED): Define. (FINALIZE_PIC): Delete definition. (INIT_EXPANDERS): Define. Clear hppa_save_pic_table_rtx here. * pa.md: Use !flag_pic rather than calling check_pic. (HImode high and lo_sum): Only accept const_int_operands. (pic_load_label): Force output to be in %r1. (pic_highpart): New pattern. Output must go into %r1. More linker trickery. (symbolic high and lo_sum): Disallow during PIC generation if source is a symbolic operand. Handle CONST_INT LO_SUM during PIC generation. Simplify. (define_split for symbolic_operand load): Do not accept a symbolic operand that is a pic_label_operand. (pic_load_label): Name this pattern. Mask least significant bits and optimize when a simple label is within reach of an ldo. (call, call_value): Emit new-style USE information for pic_offset_table_rtx. Emit code for initialization of hppa_save_pic_table_rtx and wrap it into push_topmost_sequence() and pop_topmost_sequence() calls. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@8419 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r--gcc/config/pa/pa.c131
-rw-r--r--gcc/config/pa/pa.h57
-rw-r--r--gcc/config/pa/pa.md140
3 files changed, 195 insertions, 133 deletions
diff --git a/gcc/config/pa/pa.c b/gcc/config/pa/pa.c
index 168cf0cd690..2ec55bab639 100644
--- a/gcc/config/pa/pa.c
+++ b/gcc/config/pa/pa.c
@@ -219,11 +219,29 @@ reg_or_cint_move_operand (op, mode)
}
int
-pic_operand (op, mode)
+pic_label_operand (op, mode)
rtx op;
enum machine_mode mode;
{
- return flag_pic && GET_CODE (op) == LABEL_REF;
+ if (!flag_pic)
+ return 0;
+
+ switch (GET_CODE (op))
+ {
+ case LABEL_REF:
+ return 1;
+ case SYMBOL_REF:
+ return (read_only_operand (op) && !FUNCTION_NAME_P (XSTR (op, 0)));
+ case CONST:
+ op = XEXP (op, 0);
+ return (((GET_CODE (XEXP (op, 0)) == SYMBOL_REF
+ && read_only_operand (XEXP (op, 0))
+ && !FUNCTION_NAME_P (XSTR (XEXP (op, 0), 0)))
+ || GET_CODE (XEXP (op, 0)) == LABEL_REF)
+ && GET_CODE (XEXP (op, 1)) == CONST_INT);
+ default:
+ return 0;
+ }
}
int
@@ -235,32 +253,6 @@ fp_reg_operand (op, mode)
}
-extern int current_function_uses_pic_offset_table;
-extern rtx force_reg (), validize_mem ();
-
-/* The rtx for the global offset table which is a special form
- that *is* a position independent symbolic constant. */
-rtx pic_pc_rtx;
-
-/* Ensure that we are not using patterns that are not OK with PIC. */
-
-int
-check_pic (i)
- int i;
-{
- extern rtx recog_operand[];
- switch (flag_pic)
- {
- case 1:
- if (GET_CODE (recog_operand[i]) == SYMBOL_REF
- || (GET_CODE (recog_operand[i]) == CONST
- && ! rtx_equal_p (pic_pc_rtx, recog_operand[i])))
- abort ();
- case 2:
- default:
- return 1;
- }
-}
/* Return truth value of whether OP can be used as an operand in a
three operand arithmetic insn that accepts registers of mode MODE
@@ -480,6 +472,13 @@ legitimize_pic_address (orig, mode, reg)
{
rtx pic_ref = orig;
+ /* Lables and read-only data need special handling. */
+ if (pic_label_operand (orig))
+ {
+ emit_insn (gen_pic_load_label (reg, orig));
+ current_function_uses_pic_offset_table = 1;
+ return reg;
+ }
if (GET_CODE (orig) == SYMBOL_REF)
{
if (reg == 0)
@@ -487,15 +486,12 @@ legitimize_pic_address (orig, mode, reg)
if (flag_pic == 2)
{
- emit_insn (gen_rtx (SET, VOIDmode, reg,
- gen_rtx (HIGH, Pmode, orig)));
- emit_insn (gen_rtx (SET, VOIDmode, reg,
- gen_rtx (LO_SUM, Pmode, reg, orig)));
- orig = reg;
+ emit_insn (gen_pic_highpart (reg, pic_offset_table_rtx, orig));
+ pic_ref = (gen_rtx (MEM, Pmode, gen_rtx (LO_SUM, Pmode, reg, orig)));
}
- pic_ref = gen_rtx (MEM, Pmode,
- gen_rtx (PLUS, Pmode,
- pic_offset_table_rtx, orig));
+ else
+ pic_ref = gen_rtx (MEM, Pmode,
+ gen_rtx (PLUS, Pmode, pic_offset_table_rtx, orig));
current_function_uses_pic_offset_table = 1;
RTX_UNCHANGING_P (pic_ref) = 1;
emit_move_insn (reg, pic_ref);
@@ -531,24 +527,6 @@ legitimize_pic_address (orig, mode, reg)
return pic_ref;
}
-/* Emit special PIC prologues and epilogues. */
-
-void
-finalize_pic ()
-{
- if (hppa_save_pic_table_rtx)
- {
- emit_insn_after (gen_rtx (SET, VOIDmode,
- hppa_save_pic_table_rtx,
- gen_rtx (REG, Pmode, PIC_OFFSET_TABLE_REGNUM)),
- get_insns ());
- /* Need to emit this whether or not we obey regdecls,
- since setjmp/longjmp can cause life info to screw up. */
- hppa_save_pic_table_rtx = 0;
- }
- emit_insn (gen_rtx (USE, VOIDmode, pic_offset_table_rtx));
-}
-
/* Try machine-dependent ways of modifying an illegitimate address
to be legitimate. If we find one, return the new, valid address.
This macro is used in only one place: `memory_address' in explow.c.
@@ -607,6 +585,9 @@ hppa_legitimize_address (x, oldx, mode)
{
rtx orig = x;
+ if (flag_pic)
+ return legitimize_pic_address (x, mode, gen_reg_rtx (Pmode));
+
/* Strip off CONST. */
if (GET_CODE (x) == CONST)
x = XEXP (x, 0);
@@ -727,9 +708,6 @@ hppa_legitimize_address (x, oldx, mode)
}
}
- if (flag_pic)
- return legitimize_pic_address (x, mode, gen_reg_rtx (Pmode));
-
return orig;
}
@@ -895,16 +873,16 @@ emit_move_sequence (operands, mode, scratch_reg)
rtx temp;
if (reload_in_progress || reload_completed)
- temp = operand0;
+ temp = scratch_reg ? scratch_reg : operand0;
else
temp = gen_reg_rtx (Pmode);
operands[1] = legitimize_pic_address (operand1, mode, temp);
- emit_insn (gen_rtx (SET, VOIDmode, operand0, operands[1]));
+ emit_insn (gen_rtx (SET, VOIDmode, operand0, operands[1]));
}
- /* On the HPPA, references to data space are supposed to */
- /* use dp, register 27, but showing it in the RTL inhibits various
- cse and loop optimizations. */
+ /* On the HPPA, references to data space are supposed to use dp,
+ register 27, but showing it in the RTL inhibits various cse
+ and loop optimizations. */
else
{
rtx temp, set, const_part = NULL;
@@ -982,8 +960,16 @@ read_only_operand (operand)
{
if (GET_CODE (operand) == CONST)
operand = XEXP (XEXP (operand, 0), 0);
- if (GET_CODE (operand) == SYMBOL_REF)
- return SYMBOL_REF_FLAG (operand) || CONSTANT_POOL_ADDRESS_P (operand);
+ if (flag_pic)
+ {
+ if (GET_CODE (operand) == SYMBOL_REF)
+ return SYMBOL_REF_FLAG (operand) && !CONSTANT_POOL_ADDRESS_P (operand);
+ }
+ else
+ {
+ if (GET_CODE (operand) == SYMBOL_REF)
+ return SYMBOL_REF_FLAG (operand) || CONSTANT_POOL_ADDRESS_P (operand);
+ }
return 1;
}
@@ -2950,7 +2936,7 @@ output_global_address (file, x)
if (GET_CODE (x) == SYMBOL_REF && read_only_operand (x))
assemble_name (file, XSTR (x, 0));
- else if (GET_CODE (x) == SYMBOL_REF)
+ else if (GET_CODE (x) == SYMBOL_REF && !flag_pic)
{
assemble_name (file, XSTR (x, 0));
fprintf (file, "-$global$");
@@ -2994,7 +2980,7 @@ output_global_address (file, x)
sep = "-";
else abort ();
- if (!read_only_operand (base))
+ if (!read_only_operand (base) && !flag_pic)
fprintf (file, "-$global$");
fprintf (file, "%s", sep);
if (offset) fprintf (file,"%d", offset);
@@ -3261,6 +3247,14 @@ secondary_reload_class (class, mode, in)
{
int regno = true_regnum (in);
+ /* Trying to load a constant into a FP register during PIC code
+ generation will require %r1 as a scratch register. */
+ if (flag_pic == 2
+ && GET_MODE_CLASS (mode) == MODE_INT
+ && FP_REG_CLASS_P (class)
+ && (GET_CODE (in) == CONST_INT || GET_CODE (in) == CONST_DOUBLE))
+ return R1_REGS;
+
if (((regno >= FIRST_PSEUDO_REGISTER || regno == -1)
&& GET_MODE_CLASS (mode) == MODE_INT
&& FP_REG_CLASS_P (class))
@@ -3270,6 +3264,11 @@ secondary_reload_class (class, mode, in)
if (GET_CODE (in) == HIGH)
in = XEXP (in, 0);
+ if (!flag_pic
+ && symbolic_operand (in, VOIDmode)
+ && read_only_operand (in))
+ return NO_REGS;
+
if (class != R1_REGS && symbolic_operand (in, VOIDmode))
return R1_REGS;
diff --git a/gcc/config/pa/pa.h b/gcc/config/pa/pa.h
index bc7624d27e1..cf880aff622 100644
--- a/gcc/config/pa/pa.h
+++ b/gcc/config/pa/pa.h
@@ -182,21 +182,6 @@ extern int target_flags;
#define WCHAR_TYPE "unsigned int"
#define WCHAR_TYPE_SIZE 32
-/* Sometimes certain combinations of command options do not make sense
- on a particular target machine. You can define a macro
- `OVERRIDE_OPTIONS' to take account of this. This macro, if
- defined, is executed once just after all the command options have
- been parsed.
-
- On the PA, it is used to explicitly warn the user that -fpic and -fPIC
- do not work. */
-
-#define OVERRIDE_OPTIONS \
-{ \
- if (flag_pic != 0) \
- warning ("-fpic and -fPIC are not supported on the PA."); \
-}
-
/* Show we can debug even without a frame pointer. */
#define CAN_DEBUG_WITHOUT_FP
@@ -495,8 +480,12 @@ extern int target_flags;
data references. */
#define PIC_OFFSET_TABLE_REGNUM 19
+#define PIC_OFFSET_TABLE_REG_CALL_CLOBBERED 1
-#define FINALIZE_PIC finalize_pic ()
+/* Initialize hppa_save_pic_table_rtx before RTL generation for
+ each function. We used to do this in FINALIZE_PIC, but FINALIZE_PIC
+ isn't always called for static inline functions. */
+#define INIT_EXPANDERS hppa_save_pic_table_rtx = 0;
/* SOM ABI says that objects larger than 64 bits are returned in memory. */
#define RETURN_IN_MEMORY(TYPE) \
@@ -1185,8 +1174,9 @@ extern union tree_node *current_function_decl;
floating-point, except for floating-point zero. */
#define LEGITIMATE_CONSTANT_P(X) \
- (GET_MODE_CLASS (GET_MODE (X)) != MODE_FLOAT \
- || (X) == CONST0_RTX (GET_MODE (X)))
+ ((GET_MODE_CLASS (GET_MODE (X)) != MODE_FLOAT \
+ || (X) == CONST0_RTX (GET_MODE (X))) \
+ && !(flag_pic && function_label_operand (X, VOIDmode)))
/* Subroutine for EXTRA_CONSTRAINT.
@@ -1307,9 +1297,7 @@ extern union tree_node *current_function_decl;
&& REG_OK_FOR_BASE_P (XEXP (X, 1))) \
goto ADDR; \
else if (flag_pic == 1 \
- && GET_CODE (XEXP (X, 1)) != REG \
- && GET_CODE (XEXP (X, 1)) != LO_SUM \
- && GET_CODE (XEXP (X, 1)) != MEM) \
+ && GET_CODE (XEXP (X, 1)) == SYMBOL_REF)\
goto ADDR; \
} \
else if (REG_P (XEXP (X, 0)) \
@@ -1427,6 +1415,17 @@ while (0)
1 + (SYMBOL_NAME)[1] == '@'\
: (SYMBOL_NAME)[0] == '@'))
+/* Arghh. This is used for stuff in the constant pool; this may include
+ function addresses on the PA, which during PIC code generation must
+ reside in the data space. Unfortuantely, there's no way to determine
+ if a particular label in the constant pool refers to a function address.
+ So just force everything into the data space during PIC generation. */
+#define SELECT_RTX_SECTION(RTX,MODE) \
+ if (flag_pic) \
+ data_section (); \
+ else \
+ readonly_data_section ();
+
/* Specify the machine mode that this machine uses
for the index in the tablejump instruction. */
#define CASE_VECTOR_MODE DImode
@@ -1682,6 +1681,10 @@ do { fprintf (FILE, "\t.SPACE $PRIVATE$\n\
#define EXTRA_SECTIONS in_bss, in_readonly_data
+/* FIXME: GAS doesn't grok expressions involving two symbols in different
+ segments (aka subspaces). Two avoid creating such expressions, we place
+ readonly data into the $CODE$ subspace when generating PIC code. If
+ GAS ever handles such expressions, this hack can disappear. */
#define EXTRA_SECTION_FUNCTIONS \
void \
bss_section () \
@@ -1697,7 +1700,10 @@ readonly_data () \
{ \
if (in_section != in_readonly_data) \
{ \
- fprintf (asm_out_file, "%s\n", READONLY_DATA_ASM_OP); \
+ if (flag_pic) \
+ fprintf (asm_out_file, "%s\n", TEXT_SECTION_ASM_OP); \
+ else \
+ fprintf (asm_out_file, "%s\n", READONLY_DATA_ASM_OP); \
in_section = in_readonly_data; \
} \
}
@@ -1980,7 +1986,12 @@ readonly_data () \
fprintf (FILE, "%d(0,%s)", offset, reg_names [REGNO (base)]); \
break; \
case LO_SUM: \
- fputs ("R'", FILE); \
+ if (flag_pic == 0 || !symbolic_operand (XEXP (addr, 1))) \
+ fputs ("R'", FILE); \
+ else if (flag_pic == 1) \
+ abort (); \
+ else if (flag_pic == 2) \
+ fputs ("RT'", FILE); \
output_global_address (FILE, XEXP (addr, 1)); \
fputs ("(", FILE); \
output_operand (XEXP (addr, 0), 0); \
diff --git a/gcc/config/pa/pa.md b/gcc/config/pa/pa.md
index 81b3341e507..3bb5b073193 100644
--- a/gcc/config/pa/pa.md
+++ b/gcc/config/pa/pa.md
@@ -1124,10 +1124,11 @@
(set_attr "length" "4")])
;; For pic
-(define_insn ""
- [(set (match_operand:SI 0 "register_operand" "=r")
- (match_operand:SI 1 "pic_operand" "i"))
- (clobber (match_scratch:SI 2 "=a"))]
+;; Note since this pattern can be created at reload time (via movsi), all
+;; the same rules for movsi apply here. (no new pseudos, no temporaries).
+(define_insn "pic_load_label"
+ [(set (match_operand:SI 0 "register_operand" "=a")
+ (match_operand:SI 1 "pic_label_operand" ""))]
""
"*
{
@@ -1138,14 +1139,43 @@
xoperands[0] = operands[0];
xoperands[1] = operands[1];
xoperands[2] = label_rtx;
- output_asm_insn (\"bl .+8,%0\;addil L'%1-%2,%0\", xoperands);
- ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\", CODE_LABEL_NUMBER (label_rtx));
- output_asm_insn (\"ldo R'%1-%2(1),%0\", xoperands);
+ output_asm_insn (\"bl .+8,%0\", xoperands);
+ output_asm_insn (\"depi 0,31,2,%0\", xoperands);
+ ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
+ CODE_LABEL_NUMBER (label_rtx));
+
+ /* If we're trying to load the address of a label that happens to be
+ close, then we can use a shorter sequence. */
+ if (GET_CODE (operands[1]) == LABEL_REF
+ && insn_addresses
+ && abs (insn_addresses[INSN_UID (XEXP (operands[1], 0))]
+ - insn_current_address) < 8100)
+ {
+ /* Prefixing with R% here is wrong, it extracts just 11 bits and is
+ always non-negative. */
+ output_asm_insn (\"ldo %1-%2(%0),%0\", xoperands);
+ }
+ else
+ {
+ output_asm_insn (\"addil L%%%1-%2,%0\", xoperands);
+ output_asm_insn (\"ldo R%%%1-%2(%0),%0\", xoperands);
+ }
return \"\";
- }
-"
+}"
[(set_attr "type" "multi")
- (set_attr "length" "12")])
+ (set_attr "length" "16")]) ; 12 or 16
+
+(define_insn "pic_highpart"
+ [(set (match_operand:SI 0 "register_operand" "=a")
+ (plus (match_operand:SI 1 "register_operand" "r")
+ (high:SI (match_operand 2 "" ""))))]
+ "symbolic_operand (operands[2], Pmode)
+ && ! function_label_operand (operands[2])
+ && ! read_only_operand (operands[2])
+ && flag_pic == 2"
+ "addil LT'%G2,%1"
+ [(set_attr "type" "binary")
+ (set_attr "length" "4")])
;; Always use addil rather than ldil;add sequences. This allows the
;; HP linker to eliminate the dp relocation if the symbolic operand
@@ -1155,9 +1185,9 @@
(high:SI (match_operand 1 "" "")))]
"symbolic_operand (operands[1], Pmode)
&& ! function_label_operand (operands[1])
- && ! read_only_operand (operands[1])"
- "@
- addil L'%G1,%%r27"
+ && ! read_only_operand (operands[1])
+ && ! flag_pic"
+ "addil L'%G1,%%r27"
[(set_attr "type" "binary")
(set_attr "length" "4")])
@@ -1199,7 +1229,8 @@
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r")
(high:SI (match_operand 1 "" "")))]
- "check_pic (1) && !is_function_label_plus_const (operands[1])"
+ "(!flag_pic || !symbolic_operand (operands[1]), Pmode)
+ && !is_function_label_plus_const (operands[1])"
"ldil L'%G1,%0"
[(set_attr "type" "move")
(set_attr "length" "4")])
@@ -1233,7 +1264,15 @@
(lo_sum:SI (match_operand:SI 1 "register_operand" "r")
(match_operand:SI 2 "immediate_operand" "i")))]
"!is_function_label_plus_const (operands[2])"
- "ldo R'%G2(%1),%0"
+ "*
+{
+ if (flag_pic == 2 && symbolic_operand (operands[2], Pmode))
+ return \"ldw RT'%G2(%1),%0\";
+ else if (flag_pic == 1 && symbolic_operand (operands[2], Pmode))
+ abort ();
+ else
+ return \"ldo R'%G2(%1),%0\";
+}"
[(set_attr "length" "4")])
;; Now that a symbolic_address plus a constant is broken up early
@@ -1245,7 +1284,7 @@
[(set (match_operand:SI 0 "register_operand" "")
(match_operand:SI 1 "symbolic_operand" ""))
(clobber (match_operand:SI 2 "register_operand" ""))]
- ""
+ "! (flag_pic && pic_label_operand (operands[1], SImode))"
[(set (match_dup 2) (high:SI (match_dup 1)))
(set (match_dup 0) (lo_sum:SI (match_dup 2) (match_dup 1)))]
"")
@@ -1337,8 +1376,8 @@
(define_insn ""
[(set (match_operand:HI 0 "register_operand" "=r")
- (high:HI (match_operand 1 "" "")))]
- "check_pic (1)"
+ (high:HI (match_operand 1 "const_int_operand" "")))]
+ ""
"ldil L'%G1,%0"
[(set_attr "type" "move")
(set_attr "length" "4")])
@@ -1346,7 +1385,7 @@
(define_insn ""
[(set (match_operand:HI 0 "register_operand" "=r")
(lo_sum:HI (match_operand:HI 1 "register_operand" "r")
- (match_operand 2 "immediate_operand" "i")))]
+ (match_operand 2 "const_int_operand" "i")))]
""
"ldo R'%G2(%1),%0"
[(set_attr "length" "4")])
@@ -1651,7 +1690,7 @@
(define_insn ""
[(set (match_operand:DI 0 "register_operand" "=r")
(high:DI (match_operand 1 "" "")))]
- "check_pic (1)"
+ ""
"*
{
rtx op0 = operands[0];
@@ -3102,10 +3141,7 @@
"
{
rtx op;
-
- if (flag_pic)
- emit_insn (gen_rtx (USE, VOIDmode,
- gen_rtx (REG, Pmode, PIC_OFFSET_TABLE_REGNUM)));
+ rtx call_insn;
if (TARGET_LONG_CALLS)
op = force_reg (SImode, XEXP (operands[0], 0));
@@ -3118,17 +3154,27 @@
to change the named call into an indirect call in some cases (using
two patterns keeps CSE from performing this optimization). */
if (GET_CODE (op) == SYMBOL_REF)
- emit_call_insn (gen_call_internal_symref (op, operands[1]));
+ call_insn = emit_call_insn (gen_call_internal_symref (op, operands[1]));
else
- emit_call_insn (gen_call_internal_reg (force_reg (SImode, op),
- operands[1]));
+ call_insn = emit_call_insn (gen_call_internal_reg (force_reg (SImode, op),
+ operands[1]));
if (flag_pic)
{
+ use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), pic_offset_table_rtx);
+
if (!hppa_save_pic_table_rtx)
- hppa_save_pic_table_rtx = gen_reg_rtx (Pmode);
- emit_insn (gen_rtx (SET, VOIDmode,
- gen_rtx (REG, Pmode, PIC_OFFSET_TABLE_REGNUM),
+ {
+ hppa_save_pic_table_rtx = gen_reg_rtx (Pmode);
+ push_topmost_sequence ();
+ emit_insn_after (gen_rtx (SET, VOIDmode,
+ hppa_save_pic_table_rtx,
+ pic_offset_table_rtx),
+ get_insns ());
+ pop_topmost_sequence ();
+ }
+
+ emit_insn (gen_rtx (SET, VOIDmode, pic_offset_table_rtx,
hppa_save_pic_table_rtx));
}
DONE;
@@ -3173,15 +3219,11 @@
(call (match_operand:SI 1 "" "")
(match_operand 2 "" "")))
(clobber (reg:SI 2))])]
- ;;- Don't use operand 1 for most machines.
""
"
{
rtx op;
-
- if (flag_pic)
- emit_insn (gen_rtx (USE, VOIDmode,
- gen_rtx (REG, Pmode, PIC_OFFSET_TABLE_REGNUM)));
+ rtx call_insn;
if (TARGET_LONG_CALLS)
op = force_reg (SImode, XEXP (operands[1], 0));
@@ -3194,19 +3236,30 @@
to change the named call into an indirect call in some cases (using
two patterns keeps CSE from performing this optimization). */
if (GET_CODE (op) == SYMBOL_REF)
- emit_call_insn (gen_call_value_internal_symref (operands[0], op,
- operands[2]));
+ call_insn = emit_call_insn (gen_call_value_internal_symref (operands[0],
+ op,
+ operands[2]));
else
- emit_call_insn (gen_call_value_internal_reg (operands[0],
- force_reg (SImode, op),
- operands[2]));
+ call_insn = emit_call_insn (gen_call_value_internal_reg (operands[0],
+ force_reg (SImode, op),
+ operands[2]));
if (flag_pic)
{
+ use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), pic_offset_table_rtx);
+
if (!hppa_save_pic_table_rtx)
- hppa_save_pic_table_rtx = gen_reg_rtx (Pmode);
- emit_insn (gen_rtx (SET, VOIDmode,
- gen_rtx (REG, Pmode, PIC_OFFSET_TABLE_REGNUM),
+ {
+ hppa_save_pic_table_rtx = gen_reg_rtx (Pmode);
+ push_topmost_sequence ();
+ emit_insn_after (gen_rtx (SET, VOIDmode,
+ hppa_save_pic_table_rtx,
+ pic_offset_table_rtx),
+ get_insns ());
+ pop_topmost_sequence ();
+ }
+
+ emit_insn (gen_rtx (SET, VOIDmode, pic_offset_table_rtx,
hppa_save_pic_table_rtx));
}
DONE;
@@ -3234,7 +3287,6 @@
(match_operand 2 "" "i")))
(clobber (reg:SI 2))
(use (const_int 1))]
- ;;- Don't use operand 1 for most machines.
""
"*
{