diff options
Diffstat (limited to 'gcc/config/rx')
-rw-r--r-- | gcc/config/rx/rx.c | 11 | ||||
-rw-r--r-- | gcc/config/rx/rx.h | 1 | ||||
-rw-r--r-- | gcc/config/rx/rx.md | 40 |
3 files changed, 27 insertions, 25 deletions
diff --git a/gcc/config/rx/rx.c b/gcc/config/rx/rx.c index f2429b74d28..8fa48a35827 100644 --- a/gcc/config/rx/rx.c +++ b/gcc/config/rx/rx.c @@ -874,7 +874,10 @@ rx_function_value (const_tree ret_type, /* RX ABI specifies that small integer types are promoted to int when returned by a function. */ - if (GET_MODE_SIZE (mode) > 0 && GET_MODE_SIZE (mode) < 4) + if (GET_MODE_SIZE (mode) > 0 + && GET_MODE_SIZE (mode) < 4 + && ! COMPLEX_MODE_P (mode) + ) return gen_rtx_REG (SImode, FUNC_RETURN_REGNUM); return gen_rtx_REG (mode, FUNC_RETURN_REGNUM); @@ -892,6 +895,7 @@ rx_promote_function_mode (const_tree type ATTRIBUTE_UNUSED, { if (for_return != 1 || GET_MODE_SIZE (mode) >= 4 + || COMPLEX_MODE_P (mode) || GET_MODE_SIZE (mode) < 1) return mode; @@ -1324,7 +1328,10 @@ gen_safe_add (rtx dest, rtx src, rtx val, bool is_frame_related) insn = emit_insn (gen_addsi3 (dest, src, val)); else { - insn = emit_insn (gen_addsi3_unspec (dest, src, val)); + /* Wrap VAL in an UNSPEC so that rx_is_legitimate_constant + will not reject it. */ + val = gen_rtx_CONST (SImode, gen_rtx_UNSPEC (SImode, gen_rtvec (1, val), UNSPEC_CONST)); + insn = emit_insn (gen_addsi3 (dest, src, val)); if (is_frame_related) /* We have to provide our own frame related note here diff --git a/gcc/config/rx/rx.h b/gcc/config/rx/rx.h index e2c8641685d..7acd3cee798 100644 --- a/gcc/config/rx/rx.h +++ b/gcc/config/rx/rx.h @@ -251,6 +251,7 @@ enum reg_class #define LIBCALL_VALUE(MODE) \ gen_rtx_REG (((GET_MODE_CLASS (MODE) != MODE_INT \ + || COMPLEX_MODE_P (MODE) \ || GET_MODE_SIZE (MODE) >= 4) \ ? (MODE) \ : SImode), \ diff --git a/gcc/config/rx/rx.md b/gcc/config/rx/rx.md index 9ab5f173bda..99b46b5b2e2 100644 --- a/gcc/config/rx/rx.md +++ b/gcc/config/rx/rx.md @@ -902,9 +902,9 @@ ) (define_expand "adddi3" - [(set (match_operand:DI 0 "register_operand" "") - (plus:DI (match_operand:DI 1 "register_operand" "") - (match_operand:DI 2 "rx_source_operand" "")))] + [(set (match_operand:DI 0 "register_operand") + (plus:DI (match_operand:DI 1 "register_operand") + (match_operand:DI 2 "rx_source_operand")))] "" { rtx op0l, op0h, op1l, op1h, op2l, op2h; @@ -961,8 +961,18 @@ if (rtx_equal_p (op0l, op1l)) ; + /* It is preferable that op0l == op1l... */ else if (rtx_equal_p (op0l, op2l)) x = op1l, op1l = op2l, op2l = x; + /* ... but it is only a requirement if op2l == MEM. */ + else if (MEM_P (op2l)) + { + /* Let's hope that we still have a scratch register free. */ + gcc_assert (op1h != scratch); + emit_move_insn (scratch, op2l); + op2l = scratch; + } + emit_insn (gen_addsi3_flags (op0l, op1l, op2l)); if (rtx_equal_p (op0h, op1h)) @@ -978,22 +988,6 @@ DONE; }) -;; A pattern to add an integer to a register, regardless of the -;; setting of the -mmax-constant-size command line switch. -;; See rx.c:gen_safe_add() for more details. -(define_insn "addsi3_unspec" - [(set (match_operand:SI 0 "register_operand" "=r,r") - (plus:SI (match_operand:SI 1 "register_operand" "%0,r") - (const:SI (unspec:SI [(match_operand 2 "const_int_operand" "n,n")] UNSPEC_CONST)))) - (clobber (reg:CC CC_REG))] - "" - "@ - add\t%2, %0 - add\t%2, %1, %0" - [(set_attr "timings" "11") - (set_attr "length" "6")] -) - (define_insn "andsi3" [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r,r,r") (and:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0,r,r,0") @@ -1483,9 +1477,9 @@ ) (define_expand "subdi3" - [(set (match_operand:DI 0 "register_operand" "") - (minus:DI (match_operand:DI 1 "register_operand" "") - (match_operand:DI 2 "rx_source_operand" "")))] + [(set (match_operand:DI 0 "register_operand") + (minus:DI (match_operand:DI 1 "register_operand") + (match_operand:DI 2 "rx_compare_operand")))] "" { rtx op0l, op0h, op1l, op1h, op2l, op2h; @@ -1504,7 +1498,7 @@ (define_insn_and_split "subdi3_internal" [(set (match_operand:SI 0 "register_operand" "=&r,&r") (minus:SI (match_operand:SI 2 "register_operand" " 0, r") - (match_operand:SI 3 "rx_source_operand" "rnQ, r"))) + (match_operand:SI 3 "rx_compare_operand" "rQ, r"))) (set (match_operand:SI 1 "register_operand" "= r, r") (minus:SI (minus:SI |