This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[3.3 patch] mcore: Fix PR target/13373.
- From: Kazu Hirata <kazu at cs dot umass dot edu>
- To: gcc-patches at gcc dot gnu dot org
- Cc: gdr at integrable-solutions dot net, rsandifo at redhat dot com, nickc at redhat dot com
- Date: Wed, 24 Dec 2003 16:37:13 -0500 (EST)
- Subject: [3.3 patch] mcore: Fix PR target/13373.
Hi,
Attached is a patch to fix PR 13373. This mcore-specific patch fixes
so many regressions while introducing one.
For -mbig-endian
-FAIL: gcc.c-torture/execute/20000528-1.c execution
-FAIL: gcc.c-torture/execute/20000914-1.c execution
-FAIL: gcc.c-torture/execute/20010224-1.c execution
-FAIL: gcc.c-torture/execute/20020108-1.c execution
-FAIL: gcc.c-torture/execute/20020215-1.c execution
-FAIL: gcc.c-torture/execute/20030218-1.c execution
-FAIL: gcc.c-torture/execute/20030224-2.c execution
-FAIL: gcc.c-torture/execute/920501-9.c execution
-FAIL: gcc.c-torture/execute/920726-1.c execution
-FAIL: gcc.c-torture/execute/920728-1.c execution
-FAIL: gcc.c-torture/execute/930513-1.c execution
-FAIL: gcc.c-torture/execute/930603-3.c execution
-FAIL: gcc.c-torture/execute/960327-1.c execution
-FAIL: gcc.c-torture/execute/981206-1.c execution
-FAIL: gcc.c-torture/execute/bf-pack-1.c execution
-FAIL: gcc.c-torture/execute/longlong.c compilation
-FAIL: gcc.c-torture/execute/strcmp-1.c execution
-FAIL: gcc.c-torture/execute/strct-pack-1.c execution
-FAIL: gcc.c-torture/execute/strct-pack-4.c execution
-FAIL: gcc.c-torture/execute/string-opt-6.c execution
-FAIL: gcc.c-torture/execute/strncmp-1.c execution
-FAIL: gcc.c-torture/execute/struct-ret-2.c execution
+FAIL: gcc.c-torture/execute/struct-ret-1.c execution <- Look!
-FAIL: gcc.c-torture/execute/va-arg-22.c execution
-FAIL: gcc.c-torture/execute/ieee/920810-1.c execution
-FAIL: gcc.c-torture/execute/ieee/minuszero.c execution
-FAIL: gcc.dg/20001023-1.c execution test
For -mlittle-endian
-FAIL: gcc.c-torture/execute/longlong.c compilation
To be honest, I have done no analysis. As I am not familiar with the
port, I'll leave this up to the original submitter, Richard Sandiford,
and other people.
Kazu Hirata
2003-12-24 Kazu Hirata <kazu@cs.umass.edu>
Backport from mainline:
2003-09-12 Richard Sandiford <rsandifo@redhat.com>
PR target/13373
* config/mcore/mcore-protos.h (mcore_r15_operand_p): Declare.
(mcore_secondary_reload_class): Declare.
(mcore_output_inline_const_forced): Remove.
* config/mcore/mcore.md (movsi): Remove the code that forced
non-inlineable constants into a register if the target was r15
or the stack pointer. Remove constant restrictions from the main
define_insn. Remove r <- I, r <- M and r <- N alternatives in favor
of an r <- P alternative. Remove fallback define_insn for reload.
(movhi, movqi): Use gen_lowpart rather than gen_SUBREG. Remove reload
define_insn. Use mcore_output_move in the remaining define_insn.
Adjust condition and constraints in the way as for movsi.
(movdi): Always split unacceptable constants into two. Use
simplify_gen_subreg instead of operand_subword{,_force}.
* config/mcore/mcore.c (mcore_output_inline_const_forced): Remove.
(mcore_output_move): Support HImode and QImode moves as well.
(mcore_m15_operand_p): New function.
(mcore_reload_class): Use it to detect cases where LRW_REGS are better.
(mcore_secondary_reload_class): New function.
* config/mcore/mcore.h (SECONDARY_RELOAD_CLASS): Redefine in
terms of mcore_secondary_reload_class.
Index: mcore-protos.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/mcore/mcore-protos.h,v
retrieving revision 1.10
diff -c -r1.10 mcore-protos.h
*** mcore-protos.h 4 Jun 2002 07:09:11 -0000 1.10
--- mcore-protos.h 24 Dec 2003 15:24:08 -0000
***************
*** 69,74 ****
--- 69,76 ----
extern void mcore_print_operand PARAMS ((FILE *, rtx, int));
extern rtx mcore_gen_compare_reg PARAMS ((RTX_CODE));
extern int mcore_symbolic_address_p PARAMS ((rtx));
+ extern bool mcore_r15_operand_p PARAMS ((rtx));
+ extern enum reg_class mcore_secondary_reload_class PARAMS ((enum reg_class, enum machine_mode, rtx));
extern enum reg_class mcore_reload_class PARAMS ((rtx, enum reg_class));
extern int mcore_is_same_reg PARAMS ((rtx, rtx));
extern int mcore_arith_S_operand PARAMS ((rtx));
***************
*** 76,82 ****
#ifdef HAVE_MACHINE_MODES
extern const char * mcore_output_move PARAMS ((rtx, rtx *, enum machine_mode));
extern const char * mcore_output_movedouble PARAMS ((rtx *, enum machine_mode));
- extern const char * mcore_output_inline_const_forced PARAMS ((rtx, rtx *, enum machine_mode));
extern int mcore_arith_reg_operand PARAMS ((rtx, enum machine_mode));
extern int mcore_general_movsrc_operand PARAMS ((rtx, enum machine_mode));
extern int mcore_general_movdst_operand PARAMS ((rtx, enum machine_mode));
--- 78,83 ----
Index: mcore.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/mcore/mcore.c,v
retrieving revision 1.40
diff -c -r1.40 mcore.c
*** mcore.c 24 Sep 2002 12:48:59 -0000 1.40
--- mcore.c 24 Dec 2003 15:24:10 -0000
***************
*** 1213,1219 ****
if (GET_CODE (XEXP (src, 0)) == LABEL_REF)
return "lrw\t%0,[%1]"; /* a-R */
else
! return "ldw\t%0,%1"; /* r-m */
}
else if (GET_CODE (src) == CONST_INT)
{
--- 1213,1229 ----
if (GET_CODE (XEXP (src, 0)) == LABEL_REF)
return "lrw\t%0,[%1]"; /* a-R */
else
! switch (GET_MODE (src)) /* r-m */
! {
! case SImode:
! return "ldw\t%0,%1";
! case HImode:
! return "ld.h\t%0,%1";
! case QImode:
! return "ld.b\t%0,%1";
! default:
! abort ();
! }
}
else if (GET_CODE (src) == CONST_INT)
{
***************
*** 1234,1333 ****
return "lrw\t%0, %1"; /* Into the literal pool. */
}
else if (GET_CODE (dst) == MEM) /* m-r */
! return "stw\t%1,%0";
abort ();
}
- /* Outputs a constant inline -- regardless of the cost.
- Useful for things where we've gotten into trouble and think we'd
- be doing an lrw into r15 (forbidden). This lets us get out of
- that pickle even after register allocation. */
-
- const char *
- mcore_output_inline_const_forced (insn, operands, mode)
- rtx insn ATTRIBUTE_UNUSED;
- rtx operands[];
- enum machine_mode mode ATTRIBUTE_UNUSED;
- {
- unsigned long value = INTVAL (operands[1]);
- unsigned long ovalue = value;
- struct piece
- {
- int low;
- int shift;
- }
- part[6];
- int i;
-
- if (mcore_const_ok_for_inline (value))
- return output_inline_const (SImode, operands);
-
- for (i = 0; (unsigned) i < ARRAY_SIZE (part); i++)
- {
- part[i].shift = 0;
- part[i].low = (value & 0x1F);
- value -= part[i].low;
-
- if (mcore_const_ok_for_inline (value))
- break;
- else
- {
- value >>= 5;
- part[i].shift = 5;
-
- while ((value & 1) == 0)
- {
- part[i].shift++;
- value >>= 1;
- }
-
- if (mcore_const_ok_for_inline (value))
- break;
- }
- }
-
- /* 5 bits per iteration, a maximum of 5 times == 25 bits and leaves
- 7 bits left in the constant -- which we know we can cover with
- a movi. The final value can't be zero otherwise we'd have stopped
- in the previous iteration. */
- if (value == 0 || ! mcore_const_ok_for_inline (value))
- abort ();
-
- /* Now, work our way backwards emitting the constant. */
-
- /* Emit the value that remains -- it will be nonzero. */
- operands[1] = GEN_INT (value);
- output_asm_insn (output_inline_const (SImode, operands), operands);
-
- while (i >= 0)
- {
- /* Shift anything we've already loaded. */
- if (part[i].shift)
- {
- operands[2] = GEN_INT (part[i].shift);
- output_asm_insn ("lsli %0,%2", operands);
- value <<= part[i].shift;
- }
-
- /* Add anything we need into the low 5 bits. */
- if (part[i].low != 0)
- {
- operands[2] = GEN_INT (part[i].low);
- output_asm_insn ("addi %0,%2", operands);
- value += part[i].low;
- }
-
- i--;
- }
-
- if (value != ovalue) /* sanity */
- abort ();
-
- /* We've output all the instructions. */
- return "";
- }
-
/* Return a sequence of instructions to perform DI or DF move.
Since the MCORE cannot move a DI or DF in one instruction, we have
to take care when we see overlapping source and dest registers. */
--- 1244,1264 ----
return "lrw\t%0, %1"; /* Into the literal pool. */
}
else if (GET_CODE (dst) == MEM) /* m-r */
! switch (GET_MODE (dst))
! {
! case SImode:
! return "stw\t%1,%0";
! case HImode:
! return "st.h\t%1,%0";
! case QImode:
! return "st.b\t%1,%0";
! default:
! abort ();
! }
abort ();
}
/* Return a sequence of instructions to perform DI or DF move.
Since the MCORE cannot move a DI or DF in one instruction, we have
to take care when we see overlapping source and dest registers. */
***************
*** 3009,3044 ****
}
! /* Return the reg_class to use when reloading the rtx X into the class
! CLASS. */
! /* If the input is (PLUS REG CONSTANT) representing a stack slot address,
! then we want to restrict the class to LRW_REGS since that ensures that
! will be able to safely load the constant.
!
! If the input is a constant that should be loaded with mvir1, then use
! ONLYR1_REGS.
!
! ??? We don't handle the case where we have (PLUS REG CONSTANT) and
! the constant should be loaded with mvir1, because that can lead to cases
! where an instruction needs two ONLYR1_REGS reloads. */
enum reg_class
mcore_reload_class (x, class)
rtx x;
enum reg_class class;
{
! enum reg_class new_class;
!
! if (class == GENERAL_REGS && CONSTANT_P (x)
! && (GET_CODE (x) != CONST_INT
! || ( ! CONST_OK_FOR_I (INTVAL (x))
! && ! CONST_OK_FOR_M (INTVAL (x))
! && ! CONST_OK_FOR_N (INTVAL (x)))))
! new_class = LRW_REGS;
! else
! new_class = class;
! return new_class;
}
/* Tell me if a pair of reg/subreg rtx's actually refer to the same
--- 2940,2992 ----
}
! /* Return true if X is something that can be moved directly into r15. */
!
! bool
! mcore_r15_operand_p (x)
! rtx x;
! {
! switch (GET_CODE (x))
! {
! case CONST_INT:
! return mcore_const_ok_for_inline (INTVAL (x));
!
! case REG:
! case SUBREG:
! case MEM:
! return 1;
!
! default:
! return 0;
! }
! }
! /* Implement SECONDARY_RELOAD_CLASS. If CLASS contains r15, and we can't
! directly move X into it, use r1-r14 as a temporary. */
! enum reg_class
! mcore_secondary_reload_class (class, mode, x)
! enum reg_class class;
! enum machine_mode mode ATTRIBUTE_UNUSED;
! rtx x;
! {
! if (TEST_HARD_REG_BIT (reg_class_contents[class], 15)
! && !mcore_r15_operand_p (x))
! return LRW_REGS;
! return NO_REGS;
! }
!
! /* Return the reg_class to use when reloading the rtx X into the class
! CLASS. If X is too complex to move directly into r15, prefer to
! use LRW_REGS instead. */
enum reg_class
mcore_reload_class (x, class)
rtx x;
enum reg_class class;
{
! if (reg_class_subset_p (LRW_REGS, class) && !mcore_r15_operand_p (x))
! return LRW_REGS;
! return class;
}
/* Tell me if a pair of reg/subreg rtx's actually refer to the same
Index: mcore.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/mcore/mcore.h,v
retrieving revision 1.41.4.1
diff -c -r1.41.4.1 mcore.h
*** mcore.h 29 Apr 2003 14:31:53 -0000 1.41.4.1
--- mcore.h 24 Dec 2003 15:24:11 -0000
***************
*** 610,616 ****
/* Return the register class of a scratch register needed to copy IN into
or out of a register in CLASS in MODE. If it can be done directly,
NO_REGS is returned. */
! #define SECONDARY_RELOAD_CLASS(CLASS, MODE, X) NO_REGS
/* Return the maximum number of consecutive registers
needed to represent mode MODE in a register of class CLASS.
--- 610,617 ----
/* Return the register class of a scratch register needed to copy IN into
or out of a register in CLASS in MODE. If it can be done directly,
NO_REGS is returned. */
! #define SECONDARY_RELOAD_CLASS(CLASS, MODE, X) \
! mcore_secondary_reload_class (CLASS, MODE, X)
/* Return the maximum number of consecutive registers
needed to represent mode MODE in a register of class CLASS.
Index: mcore.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/mcore/mcore.md,v
retrieving revision 1.7.4.1
diff -c -r1.7.4.1 mcore.md
*** mcore.md 16 May 2003 09:11:04 -0000 1.7.4.1
--- mcore.md 24 Dec 2003 15:24:12 -0000
***************
*** 1226,1326 ****
{
if (GET_CODE (operands[0]) == MEM)
operands[1] = force_reg (SImode, operands[1]);
- else if (CONSTANT_P (operands[1])
- && (GET_CODE (operands[1]) != CONST_INT
- || ( ! CONST_OK_FOR_I (INTVAL (operands[1]))
- && ! CONST_OK_FOR_M (INTVAL (operands[1]))
- && ! CONST_OK_FOR_N (INTVAL (operands[1]))
- && (! TARGET_HARDLIT ||
- ! mcore_const_ok_for_inline (INTVAL (operands[1])))))
- && ! reload_completed
- && ! reload_in_progress
- && GET_CODE (operands[0]) == REG
- && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
- && (REGNO (operands[0]) == STACK_POINTER_REGNUM
- || REGNO (operands[0]) == LK_REG))
- operands[1] = force_reg (SImode, operands[1]);
}")
- ;;; Must put a/i before r/r so that it will be preferred when the dest is
- ;;; a hard register. Must put a/R before r/m.
- ;;; DO WE NEED a/i ANYMORE?
-
(define_insn ""
! [(set (match_operand:SI 0 "mcore_general_movdst_operand" "=r,r,r,a,r,r,a,r,m")
! (match_operand:SI 1 "mcore_general_movsrc_operand" "I,M,N,i,r,c,R,m,r"))]
"(register_operand (operands[0], SImode)
! || register_operand (operands[1], SImode))
! && ! (CONSTANT_P (operands[1])
! && (GET_CODE (operands[1]) != CONST_INT
! || ( ! CONST_OK_FOR_I (INTVAL (operands[1]))
! && ! CONST_OK_FOR_M (INTVAL (operands[1]))
! && ! CONST_OK_FOR_N (INTVAL (operands[1]))))
! && GET_CODE (operands[0]) == REG
! && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER
! && (REGNO (operands[0]) == STACK_POINTER_REGNUM
! || REGNO (operands[0]) == LK_REG))"
"* return mcore_output_move (insn, operands, SImode);"
! [(set_attr "type" "move,move,move,move,move,move,load,load,store")])
- ;; This is to work around a bug in reload.
- (define_insn ""
- [(set (match_operand:SI 0 "register_operand" "=r")
- (match_operand:SI 1 "immediate_operand" "i"))]
- "((reload_in_progress || reload_completed)
- && CONSTANT_P (operands[1])
- && GET_CODE (operands[1]) == CONST_INT
- && ! CONST_OK_FOR_I (INTVAL (operands[1]))
- && ! CONST_OK_FOR_M (INTVAL (operands[1]))
- && ! CONST_OK_FOR_N (INTVAL (operands[1]))
- && GET_CODE (operands[0]) == REG
- && REGNO (operands[0]) == LK_REG)"
- "* return mcore_output_inline_const_forced (insn, operands, SImode);"
- [(set_attr "type" "load")])
-
- ;; (define_expand "reload_insi"
- ;; [(parallel [(match_operand:SI 0 "register_operand" "=r")
- ;; (match_operand:SI 1 "general_operand" "")
- ;; (match_operand:DI 2 "register_operand" "=&r")])]
- ;; ""
- ;; "
- ;; {
- ;; if (CONSTANT_P (operands[1])
- ;; && GET_CODE (operands[1]) == CONST_INT
- ;; && ! CONST_OK_FOR_I (INTVAL (operands[1]))
- ;; && ! CONST_OK_FOR_M (INTVAL (operands[1]))
- ;; && ! CONST_OK_FOR_N (INTVAL (operands[1]))
- ;; && GET_CODE (operands[0]) == REG
- ;; && (REGNO (operands[0]) == STACK_POINTER_REGNUM
- ;; || REGNO (operands[0]) == LK_REG))
- ;; {
- ;; rtx tmp;
- ;;
- ;; if ( REGNO (operands[2]) == REGNO (operands[0])
- ;; || REGNO (operands[2]) == STACK_POINTER_REGNUM
- ;; || REGNO (operands[2]) == LK_REG)
- ;; tmp = gen_rtx_REG (SImode, REGNO (operands[2]) + 1);
- ;; else
- ;; tmp = gen_rtx_REG (SImode, REGNO (operands[2]));
- ;;
- ;; emit_insn (gen_movsi (tmp, operands[1]));
- ;; emit_insn (gen_movsi (operands[0], tmp));
- ;; DONE;
- ;; }
- ;; emit_insn (gen_movsi (operands[0], operands[1]));
- ;; DONE;
- ;; }"
- ;; )
-
-
-
;;
;; HImode
;;
- ;;; ??? This isn't guaranteed to work. It should be more like the SImode
- ;;; patterns.
-
(define_expand "movhi"
[(set (match_operand:HI 0 "general_operand" "")
(match_operand:HI 1 "general_operand" ""))]
--- 1226,1245 ----
{
if (GET_CODE (operands[0]) == MEM)
operands[1] = force_reg (SImode, operands[1]);
}")
(define_insn ""
! [(set (match_operand:SI 0 "mcore_general_movdst_operand" "=r,r,a,r,a,r,m")
! (match_operand:SI 1 "mcore_general_movsrc_operand" "r,P,i,c,R,m,r"))]
"(register_operand (operands[0], SImode)
! || register_operand (operands[1], SImode))"
"* return mcore_output_move (insn, operands, SImode);"
! [(set_attr "type" "move,move,move,move,load,load,store")])
;;
;; HImode
;;
(define_expand "movhi"
[(set (match_operand:HI 0 "general_operand" "")
(match_operand:HI 1 "general_operand" ""))]
***************
*** 1338,1410 ****
{
rtx reg = gen_reg_rtx (SImode);
emit_insn (gen_movsi (reg, operands[1]));
! operands[1] = gen_rtx (SUBREG, HImode, reg, 0);
}
}")
(define_insn ""
! [(set (match_operand:HI 0 "mcore_general_movdst_operand" "=r,r,r,r,r,r,m")
! (match_operand:HI 1 "mcore_general_movsrc_operand" "r,I,M,N,c,m,r"))]
"(register_operand (operands[0], HImode)
! || register_operand (operands[1], HImode))
! && (GET_CODE (operands[1]) != CONST_INT
! || CONST_OK_FOR_M (INTVAL (operands[1]))
! || CONST_OK_FOR_N (INTVAL (operands[1]))
! || CONST_OK_FOR_I (INTVAL (operands[1])))"
! "@
! mov %0,%1
! movi %0,%1
! bgeni %0,%P1
! bmaski %0,%N1
! mvc %0
! ld.h %0,%1
! st.h %1,%0"
! [(set_attr "type" "move,move,move,move,move,load,store")])
!
! ;; Like movhi, but the const_int source can't be synthesized in
! ;; a single-instruction. Fall back to the same things that
! ;; are done for movsi in such cases. Presumes that we can
! ;; modify any parts of the register that we wish.
!
! (define_insn ""
! [(set (match_operand:HI 0 "mcore_general_movdst_operand" "=r,a")
! (match_operand:HI 1 "const_int_operand" "P,i"))]
! "GET_CODE (operands[1]) == CONST_INT
! && INTVAL (operands[1]) > 127 && INTVAL (operands[1]) < 65536"
! "*
! {
! if (GET_CODE (operands[0])== REG && REGNO (operands[0]) == 15
! && !mcore_const_ok_for_inline (INTVAL (operands[1])))
! {
! /* mcore_output_move would generate lrw r15 -- a forbidden combo */
! return mcore_output_inline_const_forced (insn, operands, SImode);
! }
! else
! return mcore_output_move (insn, operands, SImode);
! }"
! [(set_attr "type" "move")])
!
!
! ;; if we're still looking around for things to use, here's a last
! ;; ditch effort that just calls the move. We only let this happen
! ;; if we're in the reload pass.
! ;;
! (define_insn ""
! [(set (match_operand:HI 0 "mcore_general_movdst_operand" "=r,a")
! (match_operand:HI 1 "const_int_operand" "P,i"))]
! "reload_in_progress || reload_completed"
! "*
! {
! if (GET_CODE (operands[0])== REG && REGNO (operands[0]) == 15
! && !mcore_const_ok_for_inline (INTVAL (operands[1])))
! {
! /* mcore_output_move would generate lrw r15 -- a forbidden combo */
! return mcore_output_inline_const_forced (insn, operands, SImode);
! }
! else
! return mcore_output_move (insn, operands, HImode);
! }"
! [(set_attr "type" "move")])
;;
;; QImode
--- 1257,1273 ----
{
rtx reg = gen_reg_rtx (SImode);
emit_insn (gen_movsi (reg, operands[1]));
! operands[1] = gen_lowpart (HImode, reg);
}
}")
(define_insn ""
! [(set (match_operand:HI 0 "mcore_general_movdst_operand" "=r,r,a,r,r,m")
! (match_operand:HI 1 "mcore_general_movsrc_operand" "r,P,i,c,m,r"))]
"(register_operand (operands[0], HImode)
! || register_operand (operands[1], HImode))"
! "* return mcore_output_move (insn, operands, HImode);"
! [(set_attr "type" "move,move,move,move,load,store")])
;;
;; QImode
***************
*** 1427,1493 ****
{
rtx reg = gen_reg_rtx (SImode);
emit_insn (gen_movsi (reg, operands[1]));
! operands[1] = gen_rtx (SUBREG, QImode, reg, 0);
}
}")
(define_insn ""
! [(set (match_operand:QI 0 "mcore_general_movdst_operand" "=r,r,r,r,r,r,m")
! (match_operand:QI 1 "mcore_general_movsrc_operand" "r,I,M,N,c,m,r"))]
"(register_operand (operands[0], QImode)
! || register_operand (operands[1], QImode))
! && (GET_CODE (operands[1]) != CONST_INT
! || CONST_OK_FOR_M (INTVAL (operands[1]))
! || CONST_OK_FOR_N (INTVAL (operands[1]))
! || CONST_OK_FOR_I (INTVAL (operands[1])))"
! "@
! mov %0,%1
! movi %0,%1
! bgeni %0,%P1
! bmaski %0,%N1
! mvc %0
! ld.b %0,%1
! st.b %1,%0"
! [(set_attr "type" "move,move,move,move,move,load,store")])
!
! ;; cover the case where the constant is 128..255; this isn't handled
! ;; in the above case. We could if we wanted to mess with adding a
! ;; new constraint class like M,N,I.
! (define_insn ""
! [(set (match_operand:QI 0 "mcore_general_movdst_operand" "=r")
! (match_operand:QI 1 "const_int_operand" ""))]
! "GET_CODE (operands[1]) == CONST_INT
! && INTVAL (operands[1]) > 127 && INTVAL (operands[1]) < 256"
! "*
! {
! /* have a constant in range 128..255; have to do 2 insns; we can
! * do this with a movi followed by a bseti
! */
! operands[2] = GEN_INT (INTVAL (operands[1]) & 0x7f);
! return \"movi\\t%0,%2\;bseti\\t%0,7\";
! }"
! [(set_attr "type" "move")])
- ;; if we're still looking around for things to use, here's a last
- ;; ditch effort that just calls the move. We only let this happen
- ;; if we're in the reload pass.
- ;;
- (define_insn ""
- [(set (match_operand:QI 0 "mcore_general_movdst_operand" "=r,a")
- (match_operand:QI 1 "const_int_operand" "P,i"))]
- "(reload_in_progress || reload_completed)"
- "*
- {
- if (GET_CODE (operands[0])== REG && REGNO (operands[0]) == 15
- && ! mcore_const_ok_for_inline (INTVAL (operands[1])))
- {
- /* mcore_output_move would generate lrw r15 -- a forbidden combo */
- return mcore_output_inline_const_forced (insn, operands, SImode);
- }
- else
- return mcore_output_move (insn, operands, QImode);
- }"
- [(set_attr "type" "move")])
;; DImode
--- 1290,1307 ----
{
rtx reg = gen_reg_rtx (SImode);
emit_insn (gen_movsi (reg, operands[1]));
! operands[1] = gen_lowpart (QImode, reg);
}
}")
(define_insn ""
! [(set (match_operand:QI 0 "mcore_general_movdst_operand" "=r,r,a,r,r,m")
! (match_operand:QI 1 "mcore_general_movsrc_operand" "r,P,i,c,m,r"))]
"(register_operand (operands[0], QImode)
! || register_operand (operands[1], QImode))"
! "* return mcore_output_move (insn, operands, QImode);"
! [(set_attr "type" "move,move,move,move,load,store")])
;; DImode
***************
*** 1502,1516 ****
else if (GET_CODE (operands[1]) == CONST_INT
&& ! CONST_OK_FOR_I (INTVAL (operands[1]))
&& ! CONST_OK_FOR_M (INTVAL (operands[1]))
! && ! CONST_OK_FOR_N (INTVAL (operands[1]))
! && ! reload_completed
! && ! reload_in_progress
! && GET_CODE (operands[0]) == REG)
{
! emit_move_insn (operand_subword (operands[0], 0, 1, DImode),
! operand_subword_force (operands[1], 0, DImode));
! emit_move_insn (operand_subword (operands[0], 1, 1, DImode),
! operand_subword_force (operands[1], 1, DImode));
DONE;
}
}")
--- 1316,1327 ----
else if (GET_CODE (operands[1]) == CONST_INT
&& ! CONST_OK_FOR_I (INTVAL (operands[1]))
&& ! CONST_OK_FOR_M (INTVAL (operands[1]))
! && ! CONST_OK_FOR_N (INTVAL (operands[1])))
{
! int i;
! for (i = 0; i < UNITS_PER_WORD * 2; i += UNITS_PER_WORD)
! emit_move_insn (simplify_gen_subreg (SImode, operands[0], DImode, i),
! simplify_gen_subreg (SImode, operands[1], DImode, i));
DONE;
}
}")