aboutsummaryrefslogtreecommitdiffstats
path: root/gcc-4.9/gcc/config/pa
diff options
context:
space:
mode:
Diffstat (limited to 'gcc-4.9/gcc/config/pa')
-rw-r--r--gcc-4.9/gcc/config/pa/pa.c26
-rw-r--r--gcc-4.9/gcc/config/pa/pa.md25
-rw-r--r--gcc-4.9/gcc/config/pa/predicates.md21
3 files changed, 52 insertions, 20 deletions
diff --git a/gcc-4.9/gcc/config/pa/pa.c b/gcc-4.9/gcc/config/pa/pa.c
index 5a7598ca7..801982068 100644
--- a/gcc-4.9/gcc/config/pa/pa.c
+++ b/gcc-4.9/gcc/config/pa/pa.c
@@ -3235,7 +3235,12 @@ pa_assemble_integer (rtx x, unsigned int size, int aligned_p)
&& aligned_p
&& function_label_operand (x, VOIDmode))
{
- fputs (size == 8? "\t.dword\tP%" : "\t.word\tP%", asm_out_file);
+ fputs (size == 8? "\t.dword\t" : "\t.word\t", asm_out_file);
+
+ /* We don't want an OPD when generating fast indirect calls. */
+ if (!TARGET_FAST_INDIRECT_CALLS)
+ fputs ("P%", asm_out_file);
+
output_addr_const (asm_out_file, x);
fputc ('\n', asm_out_file);
return true;
@@ -4203,9 +4208,12 @@ pa_output_function_epilogue (FILE *file, HOST_WIDE_INT size ATTRIBUTE_UNUSED)
{
last_address = extra_nop ? 4 : 0;
insn = get_last_nonnote_insn ();
- last_address += INSN_ADDRESSES (INSN_UID (insn));
- if (INSN_P (insn))
- last_address += insn_default_length (insn);
+ if (insn)
+ {
+ last_address += INSN_ADDRESSES (INSN_UID (insn));
+ if (INSN_P (insn))
+ last_address += insn_default_length (insn);
+ }
last_address = ((last_address + FUNCTION_BOUNDARY / BITS_PER_UNIT - 1)
& ~(FUNCTION_BOUNDARY / BITS_PER_UNIT - 1));
}
@@ -9308,6 +9316,12 @@ pa_function_value (const_tree valtype,
|| TREE_CODE (valtype) == COMPLEX_TYPE
|| TREE_CODE (valtype) == VECTOR_TYPE)
{
+ HOST_WIDE_INT valsize = int_size_in_bytes (valtype);
+
+ /* Handle aggregates that fit exactly in a word or double word. */
+ if ((valsize & (UNITS_PER_WORD - 1)) == 0)
+ return gen_rtx_REG (TYPE_MODE (valtype), 28);
+
if (TARGET_64BIT)
{
/* Aggregates with a size less than or equal to 128 bits are
@@ -9316,7 +9330,7 @@ pa_function_value (const_tree valtype,
memory. */
rtx loc[2];
int i, offset = 0;
- int ub = int_size_in_bytes (valtype) <= UNITS_PER_WORD ? 1 : 2;
+ int ub = valsize <= UNITS_PER_WORD ? 1 : 2;
for (i = 0; i < ub; i++)
{
@@ -9328,7 +9342,7 @@ pa_function_value (const_tree valtype,
return gen_rtx_PARALLEL (BLKmode, gen_rtvec_v (ub, loc));
}
- else if (int_size_in_bytes (valtype) > UNITS_PER_WORD)
+ else if (valsize > UNITS_PER_WORD)
{
/* Aggregates 5 to 8 bytes in size are returned in general
registers r28-r29 in the same manner as other non
diff --git a/gcc-4.9/gcc/config/pa/pa.md b/gcc-4.9/gcc/config/pa/pa.md
index a9421ac2e..43b909e35 100644
--- a/gcc-4.9/gcc/config/pa/pa.md
+++ b/gcc-4.9/gcc/config/pa/pa.md
@@ -123,7 +123,7 @@
;; type "binary" insns have two input operands (1,2) and one output (0)
(define_attr "type"
- "move,unary,binary,shift,nullshift,compare,load,store,uncond_branch,branch,cbranch,fbranch,call,sibcall,dyncall,fpload,fpstore,fpalu,fpcc,fpmulsgl,fpmuldbl,fpdivsgl,fpdivdbl,fpsqrtsgl,fpsqrtdbl,multi,milli,sh_func_adrs,parallel_branch,fpstore_load,store_fpload"
+ "move,unary,binary,shift,nullshift,compare,load,store,uncond_branch,branch,cbranch,fbranch,call,sibcall,dyncall,fpload,fpstore,fpalu,fpcc,fpmulsgl,fpmuldbl,fpdivsgl,fpdivdbl,fpsqrtsgl,fpsqrtdbl,multi,milli,sh_func_adrs,parallel_branch,fpstore_load,store_fpload,trap"
(const_string "binary"))
(define_attr "pa_combine_type"
@@ -166,7 +166,7 @@
;; For conditional branches. Frame related instructions are not allowed
;; because they confuse the unwind support.
(define_attr "in_branch_delay" "false,true"
- (if_then_else (and (eq_attr "type" "!uncond_branch,branch,cbranch,fbranch,call,sibcall,dyncall,multi,milli,sh_func_adrs,parallel_branch")
+ (if_then_else (and (eq_attr "type" "!uncond_branch,branch,cbranch,fbranch,call,sibcall,dyncall,multi,milli,sh_func_adrs,parallel_branch,trap")
(eq_attr "length" "4")
(not (match_test "RTX_FRAME_RELATED_P (insn)")))
(const_string "true")
@@ -175,7 +175,7 @@
;; Disallow instructions which use the FPU since they will tie up the FPU
;; even if the instruction is nullified.
(define_attr "in_nullified_branch_delay" "false,true"
- (if_then_else (and (eq_attr "type" "!uncond_branch,branch,cbranch,fbranch,call,sibcall,dyncall,multi,milli,sh_func_adrs,fpcc,fpalu,fpmulsgl,fpmuldbl,fpdivsgl,fpdivdbl,fpsqrtsgl,fpsqrtdbl,parallel_branch")
+ (if_then_else (and (eq_attr "type" "!uncond_branch,branch,cbranch,fbranch,call,sibcall,dyncall,multi,milli,sh_func_adrs,fpcc,fpalu,fpmulsgl,fpmuldbl,fpdivsgl,fpdivdbl,fpsqrtsgl,fpsqrtdbl,parallel_branch,trap")
(eq_attr "length" "4")
(not (match_test "RTX_FRAME_RELATED_P (insn)")))
(const_string "true")
@@ -184,7 +184,7 @@
;; For calls and millicode calls. Allow unconditional branches in the
;; delay slot.
(define_attr "in_call_delay" "false,true"
- (cond [(and (eq_attr "type" "!uncond_branch,branch,cbranch,fbranch,call,sibcall,dyncall,multi,milli,sh_func_adrs,parallel_branch")
+ (cond [(and (eq_attr "type" "!uncond_branch,branch,cbranch,fbranch,call,sibcall,dyncall,multi,milli,sh_func_adrs,parallel_branch,trap")
(eq_attr "length" "4")
(not (match_test "RTX_FRAME_RELATED_P (insn)")))
(const_string "true")
@@ -5331,6 +5331,15 @@
[(set_attr "type" "binary,binary")
(set_attr "length" "4,4")])
+;; Trap instructions.
+
+(define_insn "trap"
+ [(trap_if (const_int 1) (const_int 0))]
+ ""
+ "{addit|addi,tc},<> 1,%%r0,%%r0"
+ [(set_attr "type" "trap")
+ (set_attr "length" "4")])
+
;; Clobbering a "register_operand" instead of a match_scratch
;; in operand3 of millicode calls avoids spilling %r1 and
;; produces better code.
@@ -8926,14 +8935,14 @@ add,l %2,%3,%3\;bv,n %%r0(%3)"
;; strength reduction is used. It is actually created when the instruction
;; combination phase combines the special loop test. Since this insn
;; is both a jump insn and has an output, it must deal with its own
-;; reloads, hence the `m' constraints. The `!' constraints direct reload
+;; reloads, hence the `Q' constraints. The `!' constraints direct reload
;; to not choose the register alternatives in the event a reload is needed.
(define_insn "decrement_and_branch_until_zero"
[(set (pc)
(if_then_else
(match_operator 2 "comparison_operator"
[(plus:SI
- (match_operand:SI 0 "reg_before_reload_operand" "+!r,!*f,*m")
+ (match_operand:SI 0 "reg_before_reload_operand" "+!r,!*f,*Q")
(match_operand:SI 1 "int5_operand" "L,L,L"))
(const_int 0)])
(label_ref (match_operand 3 "" ""))
@@ -9022,7 +9031,7 @@ add,l %2,%3,%3\;bv,n %%r0(%3)"
[(match_operand:SI 1 "register_operand" "r,r,r,r") (const_int 0)])
(label_ref (match_operand 3 "" ""))
(pc)))
- (set (match_operand:SI 0 "reg_before_reload_operand" "=!r,!*f,*m,!*q")
+ (set (match_operand:SI 0 "reg_before_reload_operand" "=!r,!*f,*Q,!*q")
(match_dup 1))]
""
"* return pa_output_movb (operands, insn, which_alternative, 0); "
@@ -9094,7 +9103,7 @@ add,l %2,%3,%3\;bv,n %%r0(%3)"
[(match_operand:SI 1 "register_operand" "r,r,r,r") (const_int 0)])
(pc)
(label_ref (match_operand 3 "" ""))))
- (set (match_operand:SI 0 "reg_before_reload_operand" "=!r,!*f,*m,!*q")
+ (set (match_operand:SI 0 "reg_before_reload_operand" "=!r,!*f,*Q,!*q")
(match_dup 1))]
""
"* return pa_output_movb (operands, insn, which_alternative, 1); "
diff --git a/gcc-4.9/gcc/config/pa/predicates.md b/gcc-4.9/gcc/config/pa/predicates.md
index 8dcfce0e9..405cf7f63 100644
--- a/gcc-4.9/gcc/config/pa/predicates.md
+++ b/gcc-4.9/gcc/config/pa/predicates.md
@@ -528,20 +528,29 @@
;; This predicate is used for branch patterns that internally handle
;; register reloading. We need to accept non-symbolic memory operands
;; after reload to ensure that the pattern is still valid if reload
-;; didn't find a hard register for the operand.
+;; didn't find a hard register for the operand. We also reject index
+;; and lo_sum DLT address as these are invalid for move destinations.
(define_predicate "reg_before_reload_operand"
(match_code "reg,mem")
{
+ rtx op0;
+
if (register_operand (op, mode))
return true;
- if (reload_completed
- && memory_operand (op, mode)
- && !symbolic_memory_operand (op, mode))
- return true;
+ if (!reload_in_progress && !reload_completed)
+ return false;
- return false;
+ if (! MEM_P (op))
+ return false;
+
+ op0 = XEXP (op, 0);
+
+ return (memory_address_p (mode, op0)
+ && !IS_INDEX_ADDR_P (op0)
+ && !IS_LO_SUM_DLT_ADDR_P (op0)
+ && !symbolic_memory_operand (op, mode));
})
;; True iff OP is a register or const_0 operand for MODE.