aboutsummaryrefslogtreecommitdiffstats
path: root/gcc-4.9/gcc/config/cris/cris.md
diff options
context:
space:
mode:
Diffstat (limited to 'gcc-4.9/gcc/config/cris/cris.md')
-rw-r--r--gcc-4.9/gcc/config/cris/cris.md60
1 files changed, 40 insertions, 20 deletions
diff --git a/gcc-4.9/gcc/config/cris/cris.md b/gcc-4.9/gcc/config/cris/cris.md
index 47f64512a..18b978786 100644
--- a/gcc-4.9/gcc/config/cris/cris.md
+++ b/gcc-4.9/gcc/config/cris/cris.md
@@ -919,6 +919,8 @@
(match_operand:SI 1 "cris_general_operand_or_symbol" ""))]
""
{
+ enum cris_symbol_type t;
+
/* If the output goes to a MEM, make sure we have zero or a register as
input. */
if (MEM_P (operands[0])
@@ -934,12 +936,12 @@
valid symbol? Can we exclude global PIC addresses with an added
offset? */
if (flag_pic
- && CONSTANT_ADDRESS_P (operands[1])
+ && CONSTANT_P (operands[1])
&& !cris_valid_pic_const (operands[1], false))
{
- enum cris_pic_symbol_type t = cris_pic_symbol_type_of (operands[1]);
+ t = cris_symbol_type_of (operands[1]);
- gcc_assert (t != cris_no_symbol);
+ gcc_assert (t != cris_no_symbol && t != cris_offsettable_symbol);
if (! REG_S_P (operands[0]))
{
@@ -1086,7 +1088,12 @@
if (!flag_pic
&& (GET_CODE (operands[1]) == SYMBOL_REF
|| GET_CODE (operands[1]) == LABEL_REF
- || GET_CODE (operands[1]) == CONST))
+ || (GET_CODE (operands[1]) == CONST
+ && (GET_CODE (XEXP (operands[1], 0)) != UNSPEC
+ || (XINT (XEXP (operands[1], 0), 1)
+ == CRIS_UNSPEC_PLT_PCREL)
+ || (XINT (XEXP (operands[1], 0), 1)
+ == CRIS_UNSPEC_PCREL)))))
{
/* FIXME: Express this through (set_attr cc none) instead,
since we can't express the ``none'' at this point. FIXME:
@@ -1169,6 +1176,12 @@
case CRIS_UNSPEC_PCREL:
case CRIS_UNSPEC_PLT_PCREL:
gcc_assert (TARGET_V32);
+ /* LAPC doesn't set condition codes; clear them to make the
+ (equivalence-marked) result of this insn not presumed
+ present. This instruction can be a PIC symbol load (for
+ a hidden symbol) which for weak symbols will be followed
+ by a test for NULL. */
+ CC_STATUS_INIT;
return "lapc %1,%0";
default:
@@ -3710,15 +3723,16 @@
{
gcc_assert (MEM_P (operands[0]));
if (flag_pic)
- cris_expand_pic_call_address (&operands[0]);
+ cris_expand_pic_call_address (&operands[0], &operands[1]);
+ else
+ operands[1] = const0_rtx;
})
-;; Accept *anything* as operand 1. Accept operands for operand 0 in
-;; order of preference.
+;; Accept operands for operand 0 in order of preference.
(define_insn "*expanded_call_non_v32"
[(call (mem:QI (match_operand:SI 0 "general_operand" "r,Q>,g"))
- (match_operand 1 "" ""))
+ (match_operand:SI 1 "cris_call_type_marker" "rM,rM,rM"))
(clobber (reg:SI CRIS_SRP_REGNUM))]
"!TARGET_V32"
"jsr %0")
@@ -3727,7 +3741,7 @@
[(call
(mem:QI
(match_operand:SI 0 "cris_nonmemory_operand_or_callable_symbol" "n,r,U,i"))
- (match_operand 1 "" ""))
+ (match_operand:SI 1 "cris_call_type_marker" "rM,rM,rM,rM"))
(clobber (reg:SI CRIS_SRP_REGNUM))]
"TARGET_V32"
"@
@@ -3740,19 +3754,21 @@
;; Parallel when calculating and reusing address of indirect pointer
;; with simple offset. (Makes most sense with PIC.) It looks a bit
;; wrong not to have the clobber last, but that's the way combine
-;; generates it (except it doesn' look into the *inner* mem, so this
+;; generates it (except it doesn't look into the *inner* mem, so this
;; just matches a peephole2). FIXME: investigate that.
(define_insn "*expanded_call_side"
[(call (mem:QI
(mem:SI
(plus:SI (match_operand:SI 0 "cris_bdap_operand" "%r, r,r")
(match_operand:SI 1 "cris_bdap_operand" "r>Rn,r,>Rn"))))
- (match_operand 2 "" ""))
+ (match_operand:SI 2 "cris_call_type_marker" "rM,rM,rM"))
(clobber (reg:SI CRIS_SRP_REGNUM))
(set (match_operand:SI 3 "register_operand" "=*0,r,r")
(plus:SI (match_dup 0)
(match_dup 1)))]
- "!TARGET_AVOID_GOTPLT && !TARGET_V32"
+ ;; Disabled until after reload until we can avoid an output reload for
+ ;; operand 3 (being forbidden for call insns).
+ "reload_completed && !TARGET_AVOID_GOTPLT && !TARGET_V32"
"jsr [%3=%0%S1]")
(define_expand "call_value"
@@ -3764,10 +3780,12 @@
{
gcc_assert (MEM_P (operands[1]));
if (flag_pic)
- cris_expand_pic_call_address (&operands[1]);
+ cris_expand_pic_call_address (&operands[1], &operands[2]);
+ else
+ operands[2] = const0_rtx;
})
-;; Accept *anything* as operand 2. The validity other than "general" of
+;; The validity other than "general" of
;; operand 0 will be checked elsewhere. Accept operands for operand 1 in
;; order of preference (Q includes r, but r is shorter, faster).
;; We also accept a PLT symbol. We output it as [rPIC+sym:GOTPLT] rather
@@ -3776,7 +3794,7 @@
(define_insn "*expanded_call_value_non_v32"
[(set (match_operand 0 "nonimmediate_operand" "=g,g,g")
(call (mem:QI (match_operand:SI 1 "general_operand" "r,Q>,g"))
- (match_operand 2 "" "")))
+ (match_operand:SI 2 "cris_call_type_marker" "rM,rM,rM")))
(clobber (reg:SI CRIS_SRP_REGNUM))]
"!TARGET_V32"
"Jsr %1"
@@ -3790,12 +3808,14 @@
(mem:SI
(plus:SI (match_operand:SI 1 "cris_bdap_operand" "%r, r,r")
(match_operand:SI 2 "cris_bdap_operand" "r>Rn,r,>Rn"))))
- (match_operand 3 "" "")))
+ (match_operand:SI 3 "cris_call_type_marker" "rM,rM,rM")))
(clobber (reg:SI CRIS_SRP_REGNUM))
(set (match_operand:SI 4 "register_operand" "=*1,r,r")
(plus:SI (match_dup 1)
(match_dup 2)))]
- "!TARGET_AVOID_GOTPLT && !TARGET_V32"
+ ;; Disabled until after reload until we can avoid an output reload for
+ ;; operand 4 (being forbidden for call insns).
+ "reload_completed && !TARGET_AVOID_GOTPLT && !TARGET_V32"
"Jsr [%4=%1%S2]"
[(set_attr "cc" "clobber")])
@@ -3805,7 +3825,7 @@
(call
(mem:QI
(match_operand:SI 1 "cris_nonmemory_operand_or_callable_symbol" "n,r,U,i"))
- (match_operand 2 "" "")))
+ (match_operand:SI 2 "cris_call_type_marker" "rM,rM,rM,rM")))
(clobber (reg:SI 16))]
"TARGET_V32"
"@
@@ -4827,7 +4847,7 @@
/* Make sure we have canonical RTX so we match the insn pattern -
not a constant in the first operand. We also require the order
(plus reg mem) to match the final pattern. */
- if (CONSTANT_P (otherop) || MEM_P (otherop))
+ if (CRIS_CONSTANT_P (otherop) || MEM_P (otherop))
{
operands[7] = operands[1];
operands[8] = otherop;
@@ -4878,7 +4898,7 @@
/* Make sure we have canonical RTX so we match the insn pattern -
not a constant in the first operand. We also require the order
(plus reg mem) to match the final pattern. */
- if (CONSTANT_P (otherop) || MEM_P (otherop))
+ if (CRIS_CONSTANT_P (otherop) || MEM_P (otherop))
{
operands[7] = operands[1];
operands[8] = otherop;