c4x.md (storeqf_int, [...]): Add new patterns with corresponding splitters to handle moves of floating point...

* config/c4x/c4x.md (storeqf_int, storeqf_int_clobber, loadqf_int,
 	loadqf_int_clobber): Add new patterns with corresponding splitters
 	to handle moves of floating point values into and out of intager
 	registers by using memory.
	* config/c4x/c4x.c (c4x_check_legit_addr): Disallow PRE_INC for modes
	other than QFmode and QImode.
	(mixed_subreg_operand): New function.
	(c4x_emit_move_sequence): If moving a floating point value into or
	out of an integer register, use the new patterns storeqf_int_clobber
	or loadqf_int_clobber.
	(reg_imm_operand, *_reg_operand): Call reg_operand instead of
	register_operand.
	(reg_operand, src_operand): Disallow operand if it satisifes
	mixed_subreg_operand.
	* config/c4x/c4x.h (mixed_subreg_operand): Add prototype.

From-SVN: r26413
This commit is contained in:
Michael Hayes 1999-04-13 15:38:12 +00:00 committed by Michael Hayes
parent b985a30f32
commit ebcc44f4ad
4 changed files with 199 additions and 9 deletions

View File

@ -1,3 +1,23 @@
Wed Apr 14 10:04:27 1999 Michael Hayes <m.hayes@elec.canterbury.ac.nz>
* config/c4x/c4x.md (storeqf_int, storeqf_int_clobber, loadqf_int,
loadqf_int_clobber): Add new patterns with corresponding splitters
to handle moves of floating point values into and out of intager
registers by using memory.
* config/c4x/c4x.c (c4x_check_legit_addr): Disallow PRE_INC for modes
other than QFmode and QImode.
(mixed_subreg_operand): New function.
(c4x_emit_move_sequence): If moving a floating point value into or
out of an integer register, use the new patterns storeqf_int_clobber
or loadqf_int_clobber.
(reg_imm_operand, *_reg_operand): Call reg_operand instead of
register_operand.
(reg_operand, src_operand): Disallow operand if it satisifes
mixed_subreg_operand.
* config/c4x/c4x.h (mixed_subreg_operand): Add prototype.
Tue Apr 13 14:49:13 1999 Jan Hubicka <hubicka@freesoft.cz> Tue Apr 13 14:49:13 1999 Jan Hubicka <hubicka@freesoft.cz>
* i386.c (agi_dependent): Handle push operation more correctly. * i386.c (agi_dependent): Handle push operation more correctly.

View File

@ -1099,6 +1099,56 @@ c4x_emit_move_sequence (operands, mode)
gen_rtx_LO_SUM (Pmode, dp_reg, XEXP (op0, 0))); gen_rtx_LO_SUM (Pmode, dp_reg, XEXP (op0, 0)));
} }
if (GET_CODE (op0) == SUBREG
&& mixed_subreg_operand (op0, mode))
{
/* We should only generate these mixed mode patterns
during RTL generation. If we need do it later on
then we'll have to emit patterns that won't clobber CC. */
if (reload_in_progress || reload_completed)
abort ();
if (GET_MODE (SUBREG_REG (op0)) == QImode)
op0 = SUBREG_REG (op0);
else if (GET_MODE (SUBREG_REG (op0)) == HImode)
{
op0 = copy_rtx (op0);
PUT_MODE (op0, QImode);
}
else
abort ();
if (mode == QFmode)
emit_insn (gen_storeqf_int_clobber (op0, op1));
else
abort ();
return 1;
}
if (GET_CODE (op1) == SUBREG
&& mixed_subreg_operand (op1, mode))
{
/* We should only generate these mixed mode patterns
during RTL generation. If we need do it later on
then we'll have to emit patterns that won't clobber CC. */
if (reload_in_progress || reload_completed)
abort ();
if (GET_MODE (SUBREG_REG (op1)) == QImode)
op1 = SUBREG_REG (op1);
else if (GET_MODE (SUBREG_REG (op1)) == HImode)
{
op1 = copy_rtx (op1);
PUT_MODE (op1, QImode);
}
else
abort ();
if (mode == QFmode)
emit_insn (gen_loadqf_int_clobber (op0, op1));
else
abort ();
return 1;
}
/* Adjust operands in case we have modified them. */ /* Adjust operands in case we have modified them. */
operands[0] = op0; operands[0] = op0;
operands[1] = op1; operands[1] = op1;
@ -1250,10 +1300,11 @@ c4x_check_legit_addr (mode, addr, strict)
being pushed on the stack. */ being pushed on the stack. */
case PRE_DEC: case PRE_DEC:
case PRE_INC:
case POST_DEC: case POST_DEC:
if (mode != QImode && mode != QFmode) if (mode != QImode && mode != QFmode)
return 0; return 0;
case PRE_INC:
case POST_INC: case POST_INC:
base = XEXP (addr, 0); base = XEXP (addr, 0);
if (! REG_P (base)) if (! REG_P (base))
@ -2653,10 +2704,29 @@ reg_operand (op, mode)
rtx op; rtx op;
enum machine_mode mode; enum machine_mode mode;
{ {
if (GET_CODE (op) == SUBREG
&& GET_MODE (op) == QFmode)
return 0;
return register_operand (op, mode); return register_operand (op, mode);
} }
int
mixed_subreg_operand (op, mode)
rtx op;
enum machine_mode mode;
{
/* Allow (subreg:HF (reg:HI)) that be generated for a union of an
int and a long double. */
if (GET_CODE (op) == SUBREG
&& (GET_MODE (op) == QFmode)
&& (GET_MODE (SUBREG_REG (op)) == QImode
|| GET_MODE (SUBREG_REG (op)) == HImode))
return 1;
return 0;
}
int int
reg_imm_operand (op, mode) reg_imm_operand (op, mode)
rtx op; rtx op;
@ -2733,7 +2803,7 @@ r0r1_reg_operand (op, mode)
rtx op; rtx op;
enum machine_mode mode; enum machine_mode mode;
{ {
if (! register_operand (op, mode)) if (! reg_operand (op, mode))
return 0; return 0;
if (GET_CODE (op) == SUBREG) if (GET_CODE (op) == SUBREG)
op = SUBREG_REG (op); op = SUBREG_REG (op);
@ -2748,7 +2818,7 @@ r2r3_reg_operand (op, mode)
rtx op; rtx op;
enum machine_mode mode; enum machine_mode mode;
{ {
if (! register_operand (op, mode)) if (! reg_operand (op, mode))
return 0; return 0;
if (GET_CODE (op) == SUBREG) if (GET_CODE (op) == SUBREG)
op = SUBREG_REG (op); op = SUBREG_REG (op);
@ -2763,7 +2833,7 @@ ext_low_reg_operand (op, mode)
rtx op; rtx op;
enum machine_mode mode; enum machine_mode mode;
{ {
if (! register_operand (op, mode)) if (! reg_operand (op, mode))
return 0; return 0;
if (GET_CODE (op) == SUBREG) if (GET_CODE (op) == SUBREG)
op = SUBREG_REG (op); op = SUBREG_REG (op);
@ -2778,7 +2848,7 @@ ext_reg_operand (op, mode)
rtx op; rtx op;
enum machine_mode mode; enum machine_mode mode;
{ {
if (! register_operand (op, mode)) if (! reg_operand (op, mode))
return 0; return 0;
if (GET_CODE (op) == SUBREG) if (GET_CODE (op) == SUBREG)
op = SUBREG_REG (op); op = SUBREG_REG (op);
@ -2795,7 +2865,7 @@ std_reg_operand (op, mode)
rtx op; rtx op;
enum machine_mode mode; enum machine_mode mode;
{ {
if (! register_operand (op, mode)) if (! reg_operand (op, mode))
return 0; return 0;
if (GET_CODE (op) == SUBREG) if (GET_CODE (op) == SUBREG)
op = SUBREG_REG (op); op = SUBREG_REG (op);
@ -2810,7 +2880,7 @@ addr_reg_operand (op, mode)
rtx op; rtx op;
enum machine_mode mode; enum machine_mode mode;
{ {
if (! register_operand (op, mode)) if (! reg_operand (op, mode))
return 0; return 0;
return c4x_a_register (op); return c4x_a_register (op);
} }
@ -2823,7 +2893,7 @@ index_reg_operand (op, mode)
rtx op; rtx op;
enum machine_mode mode; enum machine_mode mode;
{ {
if (! register_operand (op, mode)) if (! reg_operand (op, mode))
return 0; return 0;
if (GET_CODE (op) == SUBREG) if (GET_CODE (op) == SUBREG)
op = SUBREG_REG (op); op = SUBREG_REG (op);
@ -2914,6 +2984,10 @@ src_operand (op, mode)
rtx op; rtx op;
enum machine_mode mode; enum machine_mode mode;
{ {
if (GET_CODE (op) == SUBREG
&& mixed_subreg_operand (op, mode))
return 0;
if (REG_P (op)) if (REG_P (op))
return reg_operand (op, mode); return reg_operand (op, mode);

View File

@ -2655,6 +2655,8 @@ extern int reg_or_const_operand ();
extern int reg_operand (); extern int reg_operand ();
extern int mixed_subreg_operand ();
extern int reg_imm_operand (); extern int reg_imm_operand ();
extern int r0r1_reg_operand (); extern int r0r1_reg_operand ();

View File

@ -449,7 +449,9 @@
; 8 loadhf_int ; 8 loadhf_int
; 9 storehf_int ; 9 storehf_int
; 10 RSQRF ; 10 RSQRF
; 11 loadqf_int
; 12 storeqf_int
; 22 rptb_init
; ;
; C4x FUNCTIONAL UNITS ; C4x FUNCTIONAL UNITS
@ -2968,6 +2970,98 @@
DONE; DONE;
}") }")
; This can generate invalid stack slot displacements
(define_split
[(set (match_operand:QI 0 "reg_operand" "=r")
(unspec [(match_operand:QF 1 "reg_operand" "f")] 12))]
"reload_completed"
[(set (match_dup 3) (match_dup 1))
(set (match_dup 0) (match_dup 2))]
"operands[2] = assign_stack_temp (QImode, GET_MODE_SIZE (QImode), 0);
operands[3] = copy_rtx (operands[2]);
PUT_MODE (operands[3], QFmode);")
(define_insn "storeqf_int"
[(set (match_operand:QI 0 "reg_operand" "=r")
(unspec [(match_operand:QF 1 "reg_operand" "f")] 12))]
""
"#"
[(set_attr "type" "multi")])
(define_split
[(parallel [(set (match_operand:QI 0 "reg_operand" "=r")
(unspec [(match_operand:QF 1 "reg_operand" "f")] 12))
(clobber (reg:CC 21))])]
"reload_completed"
[(set (mem:QF (pre_inc:QI (reg:QI 20)))
(match_dup 1))
(parallel [(set (match_dup 0)
(mem:QI (post_dec:QI (reg:QI 20))))
(clobber (reg:CC 21))])]
"")
; We need accurate death notes for this...
;(define_peephole
; [(set (match_operand:QF 0 "reg_operand" "=f")
; (match_operand:QF 1 "memory_operand" "m"))
; (set (mem:QF (pre_inc:QI (reg:QI 20)))
; (match_dup 0))
; (parallel [(set (match_operand:QI 2 "reg_operand" "r")
; (mem:QI (post_dec:QI (reg:QI 20))))
; (clobber (reg:CC 21))])]
; ""
; "ldiu\\t%1,%0")
(define_insn "storeqf_int_clobber"
[(parallel [(set (match_operand:QI 0 "reg_operand" "=r")
(unspec [(match_operand:QF 1 "reg_operand" "f")] 12))
(clobber (reg:CC 21))])]
""
"#"
[(set_attr "type" "multi")])
; This can generate invalid stack slot displacements
(define_split
[(set (match_operand:QF 0 "reg_operand" "=f")
(unspec [(match_operand:QI 1 "reg_operand" "r")] 11))]
"reload_completed"
[(set (match_dup 2) (match_dup 1))
(set (match_dup 0) (match_dup 3))]
"operands[2] = assign_stack_temp (QImode, GET_MODE_SIZE (QImode), 0);
operands[3] = copy_rtx (operands[2]);
PUT_MODE (operands[3], QFmode);")
(define_insn "loadqf_int"
[(set (match_operand:QF 0 "reg_operand" "=f")
(unspec [(match_operand:QI 1 "reg_operand" "r")] 11))]
""
"#"
[(set_attr "type" "multi")])
(define_split
[(parallel [(set (match_operand:QF 0 "reg_operand" "=f")
(unspec [(match_operand:QI 1 "reg_operand" "r")] 11))
(clobber (reg:CC 21))])]
"reload_completed"
[(set (mem:QI (pre_inc:QI (reg:QI 20)))
(match_dup 1))
(parallel [(set (match_dup 0)
(mem:QF (post_dec:QI (reg:QI 20))))
(clobber (reg:CC 21))])]
"")
(define_insn "loadqf_int_clobber"
[(parallel [(set (match_operand:QF 0 "reg_operand" "=f")
(unspec [(match_operand:QI 1 "reg_operand" "r")] 11))
(clobber (reg:CC 21))])]
""
"#"
[(set_attr "type" "multi")])
; We must provide an alternative to store to memory in case we have to ; We must provide an alternative to store to memory in case we have to
; spill a register. ; spill a register.
(define_insn "movqf_noclobber" (define_insn "movqf_noclobber"