+2001-04-03 Alan Modra <alan@linuxcare.com.au>
+
+ * pa.h: Revise comments for TARGET_NO_SPACE_REGS and
+ TARGET_FAST_INDIRECT_CALLS.
+ * pa.c (override_options): TARGET_NO_SPACE_REGS is now OK with
+ -fPIC. Don't warn.
+ (return_addr_rtx): Short circuit export stub matching when
+ TARGET_NO_SPACE_REGS.
+ (output_millicode_call): For out of range calls, make -fPIC
+ take precedence, then TARGET_PORTABLE_RUNTIME, then ble. Don't
+ return before delay slot checks when TARGET_PORTABLE_RUNTIME.
+ * pa.md: Modify length attr calculation of all millicode insns to
+ match above.
+
2001-04-02 Geoffrey Keating <geoffk@redhat.com>
* configure.in (gcc_cv_as_leb128): Correct name of cache variable.
2001-04-03 Alan Modra <alan@linuxcare.com.au>
- * config/pa/pa.c (override_options): Remove PIC profiling warning.
+ * pa.c (override_options): Remove PIC profiling warning.
(hp_profile_labelno): Delete.
(hp_profile_label_rtx): Delete.
(hp_profile_label_name): Delete.
(hppa_init_pic_save): Emit before tail_recursion_reentry, and
cater for PROFILE_HOOK.
(hppa_profile_hook): New function.
- * config/pa/pa.h (FUNCTION_PROFILER): Now does nothing.
+ * pa.h (FUNCTION_PROFILER): Now does nothing.
(PROFILE_HOOK): Define.
(hppa_profile_hook): Declare.
(PROFILE_BEFORE_PROLOGUE): Delete.
(ASM_OUTPUT_REG_PUSH): Delete.
(ASM_OUTPUT_REG_POP): Delete.
- * config/pa/pa.md (call_profiler): Turn it into a call insn, and
- don't `use' r24. Accept function name operand, and use this and a
- locally generated label to calculate pc-rel offset to func start.
+ * pa.md (call_profiler): Turn it into a call insn, and don't `use'
+ r24. Accept function name operand, and use this and a locally
+ generated label to calculate pc-rel offset to func start.
2001-04-02 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
2001-01-31 Alan Modra <alan@linuxcare.com.au>
- * (hppa_init_pic_save): Emit the pic offset table
- reg save after last_parm_insn.
* pa.c (hppa_init_pic_save): New function.
* pa.h (hppa_init_pic_save): Declare.
* pa.md (call, call_value, sibcall, sibcall_value): Use
warning ("PIC code generation is not supported in the portable runtime model\n");
}
- if (flag_pic && (TARGET_NO_SPACE_REGS || TARGET_FAST_INDIRECT_CALLS))
+ if (flag_pic && TARGET_FAST_INDIRECT_CALLS)
{
warning ("PIC code generation is not compatible with fast indirect calls\n");
}
rtx saved_rp;
rtx ins;
- saved_rp = gen_reg_rtx (Pmode);
+ if (TARGET_64BIT)
+ return gen_rtx_MEM (Pmode, plus_constant (frameaddr, -16));
+
+ if (TARGET_NO_SPACE_REGS)
+ return gen_rtx_MEM (Pmode, plus_constant (frameaddr, -20));
/* First, we start off with the normal return address pointer from
-20[frameaddr]. */
- if (TARGET_64BIT)
- return gen_rtx_MEM (Pmode, plus_constant (frameaddr, -16));
- else
- emit_move_insn (saved_rp, plus_constant (frameaddr, -5 * UNITS_PER_WORD));
+ saved_rp = gen_reg_rtx (Pmode);
+ emit_move_insn (saved_rp, plus_constant (frameaddr, -20));
/* Get pointer to the instruction stream. We have to mask out the
privilege level from the two low order bits of the return address
but rather the return address that leads back into user code.
That return address is stored at -24[frameaddr]. */
- emit_move_insn (saved_rp, plus_constant (frameaddr, -6 * UNITS_PER_WORD));
+ emit_move_insn (saved_rp, plus_constant (frameaddr, -24));
emit_label (label);
return gen_rtx_MEM (Pmode, memory_address (Pmode, saved_rp));
rtx xoperands[4];
rtx seq_insn;
- xoperands[3] = gen_rtx_REG (SImode, 31);
- if (TARGET_64BIT)
- xoperands[3] = gen_rtx_REG (SImode, 2);
+ xoperands[3] = gen_rtx_REG (Pmode, TARGET_64BIT ? 2 : 31);
/* Handle common case -- empty delay slot or no jump in the delay slot,
and we're sure that the branch will reach the beginning of the $CODE$
delay_insn_deleted = 1;
}
- /* If we're allowed to use be/ble instructions, then this is the
- best sequence to use for a long millicode call. */
- if (TARGET_NO_SPACE_REGS || TARGET_FAST_INDIRECT_CALLS
- || ! (flag_pic || TARGET_PORTABLE_RUNTIME))
+ /* PIC long millicode call sequence. */
+ if (flag_pic)
{
xoperands[0] = call_dest;
- output_asm_insn ("ldil L%%%0,%3", xoperands);
- output_asm_insn ("{ble|be,l} R%%%0(%%sr4,%3)", xoperands);
+ xoperands[1] = gen_label_rtx ();
+ /* Get our address + 8 into %r1. */
+ output_asm_insn ("{bl|b,l} .+8,%%r1", xoperands);
+
+ /* Add %r1 to the offset of our target from the next insn. */
+ output_asm_insn ("addil L%%%0-%1,%%r1", xoperands);
+ ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
+ CODE_LABEL_NUMBER (xoperands[1]));
+ output_asm_insn ("ldo R%%%0-%1(%%r1),%%r1", xoperands);
+
+ /* Get the return address into %r31. */
+ output_asm_insn ("blr 0,%3", xoperands);
+
+ /* Branch to our target which is in %r1. */
+ output_asm_insn ("bv,n %%r0(%%r1)", xoperands);
+
+ /* Empty delay slot. Note this insn gets fetched twice and
+ executed once. To be safe we use a nop. */
output_asm_insn ("nop", xoperands);
}
/* Pure portable runtime doesn't allow be/ble; we also don't have
- PIC support int he assembler/linker, so this sequence is needed. */
+ PIC support in the assembler/linker, so this sequence is needed. */
else if (TARGET_PORTABLE_RUNTIME)
{
xoperands[0] = call_dest;
/* Empty delay slot. Note this insn gets fetched twice and
executed once. To be safe we use a nop. */
output_asm_insn ("nop", xoperands);
- return "";
}
- /* PIC long millicode call sequence. */
+ /* If we're allowed to use be/ble instructions, then this is the
+ best sequence to use for a long millicode call. */
else
{
xoperands[0] = call_dest;
- xoperands[1] = gen_label_rtx ();
- /* Get our address + 8 into %r1. */
- output_asm_insn ("{bl|b,l} .+8,%%r1", xoperands);
-
- /* Add %r1 to the offset of our target from the next insn. */
- output_asm_insn ("addil L%%%0-%1,%%r1", xoperands);
- ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
- CODE_LABEL_NUMBER (xoperands[1]));
- output_asm_insn ("ldo R%%%0-%1(%%r1),%%r1", xoperands);
-
- /* Get the return address into %r31. */
- output_asm_insn ("blr 0,%3", xoperands);
-
- /* Branch to our target which is in %r1. */
- output_asm_insn ("bv,n %%r0(%%r1)", xoperands);
-
- /* Empty delay slot. Note this insn gets fetched twice and
- executed once. To be safe we use a nop. */
+ output_asm_insn ("ldil L%%%0,%3", xoperands);
+ output_asm_insn ("{ble|be,l} R%%%0(%%sr4,%3)", xoperands);
output_asm_insn ("nop", xoperands);
}
#define MASK_DISABLE_FPREGS 2
#define TARGET_DISABLE_FPREGS (target_flags & MASK_DISABLE_FPREGS)
-/* Generate code which assumes that calls through function pointers will
- never cross a space boundary. Such assumptions are generally safe for
- building kernels and statically linked executables. Code compiled with
- this option will fail miserably if the executable is dynamically linked
- or uses nested functions!
-
- This is also used to trigger aggressive unscaled index addressing. */
+/* Generate code which assumes that all space register are equivalent.
+ Triggers aggressive unscaled index addressing and faster
+ builtin_return_address. */
#define MASK_NO_SPACE_REGS 4
#define TARGET_NO_SPACE_REGS (target_flags & MASK_NO_SPACE_REGS)
#define MASK_LONG_LOAD_STORE 512
#define TARGET_LONG_LOAD_STORE (target_flags & MASK_LONG_LOAD_STORE)
-/* Use a faster sequence for indirect calls. */
+/* Use a faster sequence for indirect calls. This assumes that calls
+ through function pointers will never cross a space boundary, and
+ that the executable is not dynamically linked. Such assumptions
+ are generally safe for building kernels and statically linked
+ executables. Code compiled with this option will fail miserably if
+ the executable is dynamically linked or uses nested functions! */
#define MASK_FAST_INDIRECT_CALLS 1024
#define TARGET_FAST_INDIRECT_CALLS (target_flags & MASK_FAST_INDIRECT_CALLS)
(const_int 0)))
(const_int 4)
-;; NO_SPACE_REGS
- (ne (symbol_ref "TARGET_NO_SPACE_REGS || TARGET_FAST_INDIRECT_CALLS")
+;; Out of reach PIC
+ (ne (symbol_ref "flag_pic")
(const_int 0))
- (const_int 8)
+ (const_int 24)
-;; Out of reach, but not PIC or PORTABLE_RUNTIME
-;; same as NO_SPACE_REGS code
- (and (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
- (const_int 0))
- (eq (symbol_ref "flag_pic")
- (const_int 0)))
- (const_int 8)]
+;; Out of reach PORTABLE_RUNTIME
+ (ne (symbol_ref "TARGET_PORTABLE_RUNTIME")
+ (const_int 0))
+ (const_int 20)]
-;; Out of range and either PIC or PORTABLE_RUNTIME
- (const_int 24)))])
+;; Out of reach, can use ble
+ (const_int 12)))])
(define_expand "muldi3"
[(set (match_operand:DI 0 "register_operand" "")
(const_int 0)))
(const_int 4)
-;; NO_SPACE_REGS
- (ne (symbol_ref "TARGET_NO_SPACE_REGS || TARGET_FAST_INDIRECT_CALLS")
+;; Out of reach PIC
+ (ne (symbol_ref "flag_pic")
(const_int 0))
- (const_int 8)
+ (const_int 24)
-;; Out of reach, but not PIC or PORTABLE_RUNTIME
-;; same as NO_SPACE_REGS code
- (and (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
- (const_int 0))
- (eq (symbol_ref "flag_pic")
- (const_int 0)))
- (const_int 8)]
+;; Out of reach PORTABLE_RUNTIME
+ (ne (symbol_ref "TARGET_PORTABLE_RUNTIME")
+ (const_int 0))
+ (const_int 20)]
-;; Out of range and either PIC or PORTABLE_RUNTIME
- (const_int 24)))])
+;; Out of reach, can use ble
+ (const_int 12)))])
(define_expand "udivsi3"
[(set (reg:SI 26) (match_operand:SI 1 "move_operand" ""))
(const_int 0)))
(const_int 4)
-;; NO_SPACE_REGS
- (ne (symbol_ref "TARGET_NO_SPACE_REGS || TARGET_FAST_INDIRECT_CALLS")
+;; Out of reach PIC
+ (ne (symbol_ref "flag_pic")
(const_int 0))
- (const_int 8)
+ (const_int 24)
-;; Out of reach, but not PIC or PORTABLE_RUNTIME
-;; same as NO_SPACE_REGS code
- (and (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
- (const_int 0))
- (eq (symbol_ref "flag_pic")
- (const_int 0)))
- (const_int 8)]
+;; Out of reach PORTABLE_RUNTIME
+ (ne (symbol_ref "TARGET_PORTABLE_RUNTIME")
+ (const_int 0))
+ (const_int 20)]
-;; Out of range and either PIC or PORTABLE_RUNTIME
- (const_int 24)))])
+;; Out of reach, can use ble
+ (const_int 12)))])
(define_expand "modsi3"
[(set (reg:SI 26) (match_operand:SI 1 "move_operand" ""))
(const_int 0)))
(const_int 4)
-;; NO_SPACE_REGS
- (ne (symbol_ref "TARGET_NO_SPACE_REGS || TARGET_FAST_INDIRECT_CALLS")
+;; Out of reach PIC
+ (ne (symbol_ref "flag_pic")
(const_int 0))
- (const_int 8)
+ (const_int 24)
-;; Out of reach, but not PIC or PORTABLE_RUNTIME
-;; same as NO_SPACE_REGS code
- (and (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
- (const_int 0))
- (eq (symbol_ref "flag_pic")
- (const_int 0)))
- (const_int 8)]
+;; Out of reach PORTABLE_RUNTIME
+ (ne (symbol_ref "TARGET_PORTABLE_RUNTIME")
+ (const_int 0))
+ (const_int 20)]
-;; Out of range and either PIC or PORTABLE_RUNTIME
- (const_int 24)))])
+;; Out of reach, can use ble
+ (const_int 12)))])
(define_expand "umodsi3"
[(set (reg:SI 26) (match_operand:SI 1 "move_operand" ""))
(const_int 0)))
(const_int 4)
-;; NO_SPACE_REGS
- (ne (symbol_ref "TARGET_NO_SPACE_REGS || TARGET_FAST_INDIRECT_CALLS")
+;; Out of reach PIC
+ (ne (symbol_ref "flag_pic")
(const_int 0))
- (const_int 8)
+ (const_int 24)
-;; Out of reach, but not PIC or PORTABLE_RUNTIME
-;; same as NO_SPACE_REGS code
- (and (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
- (const_int 0))
- (eq (symbol_ref "flag_pic")
- (const_int 0)))
- (const_int 8)]
+;; Out of reach PORTABLE_RUNTIME
+ (ne (symbol_ref "TARGET_PORTABLE_RUNTIME")
+ (const_int 0))
+ (const_int 20)]
-;; Out of range and either PIC or PORTABLE_RUNTIME
- (const_int 24)))])
+;; Out of reach, can use ble
+ (const_int 12)))])
;;- and instructions
;; We define DImode `and` so with DImode `not` we can get
rtx xoperands[2];
/* First the special case for kernels, level 0 systems, etc. */
- if (TARGET_NO_SPACE_REGS || TARGET_FAST_INDIRECT_CALLS)
+ if (TARGET_FAST_INDIRECT_CALLS)
return \"ble 0(%%sr4,%%r22)\;copy %%r31,%%r2\";
/* Now the normal case -- we can reach $$dyncall directly or
[(set_attr "type" "dyncall")
(set (attr "length")
(cond [
-;; First NO_SPACE_REGS
- (ne (symbol_ref "TARGET_NO_SPACE_REGS || TARGET_FAST_INDIRECT_CALLS")
+;; First FAST_INDIRECT_CALLS
+ (ne (symbol_ref "TARGET_FAST_INDIRECT_CALLS")
(const_int 0))
(const_int 8)
(const_int 0)))
(const_int 8)
-;; Out of reach, but not PIC or PORTABLE_RUNTIME
- (and (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
- (const_int 0))
- (eq (symbol_ref "flag_pic")
- (const_int 0)))
- (const_int 12)
+;; Out of reach PIC
+ (ne (symbol_ref "flag_pic")
+ (const_int 0))
+ (const_int 24)
+;; Out of reach PORTABLE_RUNTIME
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME")
(const_int 0))
(const_int 20)]
-;; Out of range PIC case
- (const_int 24)))])
+;; Out of reach, can use ble
+ (const_int 12)))])
(define_expand "call_value"
[(parallel [(set (match_operand 0 "" "")
rtx xoperands[2];
/* First the special case for kernels, level 0 systems, etc. */
- if (TARGET_NO_SPACE_REGS || TARGET_FAST_INDIRECT_CALLS)
+ if (TARGET_FAST_INDIRECT_CALLS)
return \"ble 0(%%sr4,%%r22)\;copy %%r31,%%r2\";
/* Now the normal case -- we can reach $$dyncall directly or
[(set_attr "type" "dyncall")
(set (attr "length")
(cond [
-;; First NO_SPACE_REGS
- (ne (symbol_ref "TARGET_NO_SPACE_REGS || TARGET_FAST_INDIRECT_CALLS")
+;; First FAST_INDIRECT_CALLS
+ (ne (symbol_ref "TARGET_FAST_INDIRECT_CALLS")
(const_int 0))
(const_int 8)
(const_int 0)))
(const_int 8)
-;; Out of reach, but not PIC or PORTABLE_RUNTIME
- (and (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
- (const_int 0))
- (eq (symbol_ref "flag_pic")
- (const_int 0)))
- (const_int 12)
+;; Out of reach PIC
+ (ne (symbol_ref "flag_pic")
+ (const_int 0))
+ (const_int 24)
+;; Out of reach PORTABLE_RUNTIME
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME")
(const_int 0))
(const_int 20)]
-;; Out of range PIC case
- (const_int 24)))])
+;; Out of reach, can use ble
+ (const_int 12)))])
;; Call subroutine returning any type.
(const_int 0)))
(const_int 28)
-;; NO_SPACE_REGS
- (ne (symbol_ref "TARGET_NO_SPACE_REGS || TARGET_FAST_INDIRECT_CALLS")
- (const_int 0))
- (const_int 32)
-
-;; Out of reach, but not PIC or PORTABLE_RUNTIME
-;; same as NO_SPACE_REGS code
- (and (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
- (const_int 0))
- (eq (symbol_ref "flag_pic")
- (const_int 0)))
- (const_int 32)
+;; Out of reach PIC
+ (ne (symbol_ref "flag_pic")
+ (const_int 0))
+ (const_int 44)
-;; PORTABLE_RUNTIME
+;; Out of reach PORTABLE_RUNTIME
(ne (symbol_ref "TARGET_PORTABLE_RUNTIME")
(const_int 0))
(const_int 40)]
-;; Out of range and PIC
- (const_int 44)))])
+;; Out of reach, can use ble
+ (const_int 32)))])
;; On the PA, the PIC register is call clobbered, so it must
;; be saved & restored around calls by the caller. If the call