diff options
Diffstat (limited to 'gcc-4.9/gcc/config/pa')
-rw-r--r-- | gcc-4.9/gcc/config/pa/pa.c | 26 | ||||
-rw-r--r-- | gcc-4.9/gcc/config/pa/pa.md | 25 | ||||
-rw-r--r-- | gcc-4.9/gcc/config/pa/predicates.md | 21 |
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. |