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:
parent
b985a30f32
commit
ebcc44f4ad
@ -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>
|
||||
|
||||
* i386.c (agi_dependent): Handle push operation more correctly.
|
||||
|
@ -1099,6 +1099,56 @@ c4x_emit_move_sequence (operands, mode)
|
||||
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. */
|
||||
operands[0] = op0;
|
||||
operands[1] = op1;
|
||||
@ -1250,10 +1300,11 @@ c4x_check_legit_addr (mode, addr, strict)
|
||||
being pushed on the stack. */
|
||||
|
||||
case PRE_DEC:
|
||||
case PRE_INC:
|
||||
case POST_DEC:
|
||||
if (mode != QImode && mode != QFmode)
|
||||
return 0;
|
||||
case PRE_INC:
|
||||
|
||||
case POST_INC:
|
||||
base = XEXP (addr, 0);
|
||||
if (! REG_P (base))
|
||||
@ -2653,10 +2704,29 @@ reg_operand (op, mode)
|
||||
rtx op;
|
||||
enum machine_mode mode;
|
||||
{
|
||||
if (GET_CODE (op) == SUBREG
|
||||
&& GET_MODE (op) == QFmode)
|
||||
return 0;
|
||||
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
|
||||
reg_imm_operand (op, mode)
|
||||
rtx op;
|
||||
@ -2733,7 +2803,7 @@ r0r1_reg_operand (op, mode)
|
||||
rtx op;
|
||||
enum machine_mode mode;
|
||||
{
|
||||
if (! register_operand (op, mode))
|
||||
if (! reg_operand (op, mode))
|
||||
return 0;
|
||||
if (GET_CODE (op) == SUBREG)
|
||||
op = SUBREG_REG (op);
|
||||
@ -2748,7 +2818,7 @@ r2r3_reg_operand (op, mode)
|
||||
rtx op;
|
||||
enum machine_mode mode;
|
||||
{
|
||||
if (! register_operand (op, mode))
|
||||
if (! reg_operand (op, mode))
|
||||
return 0;
|
||||
if (GET_CODE (op) == SUBREG)
|
||||
op = SUBREG_REG (op);
|
||||
@ -2763,7 +2833,7 @@ ext_low_reg_operand (op, mode)
|
||||
rtx op;
|
||||
enum machine_mode mode;
|
||||
{
|
||||
if (! register_operand (op, mode))
|
||||
if (! reg_operand (op, mode))
|
||||
return 0;
|
||||
if (GET_CODE (op) == SUBREG)
|
||||
op = SUBREG_REG (op);
|
||||
@ -2778,7 +2848,7 @@ ext_reg_operand (op, mode)
|
||||
rtx op;
|
||||
enum machine_mode mode;
|
||||
{
|
||||
if (! register_operand (op, mode))
|
||||
if (! reg_operand (op, mode))
|
||||
return 0;
|
||||
if (GET_CODE (op) == SUBREG)
|
||||
op = SUBREG_REG (op);
|
||||
@ -2795,7 +2865,7 @@ std_reg_operand (op, mode)
|
||||
rtx op;
|
||||
enum machine_mode mode;
|
||||
{
|
||||
if (! register_operand (op, mode))
|
||||
if (! reg_operand (op, mode))
|
||||
return 0;
|
||||
if (GET_CODE (op) == SUBREG)
|
||||
op = SUBREG_REG (op);
|
||||
@ -2810,7 +2880,7 @@ addr_reg_operand (op, mode)
|
||||
rtx op;
|
||||
enum machine_mode mode;
|
||||
{
|
||||
if (! register_operand (op, mode))
|
||||
if (! reg_operand (op, mode))
|
||||
return 0;
|
||||
return c4x_a_register (op);
|
||||
}
|
||||
@ -2823,7 +2893,7 @@ index_reg_operand (op, mode)
|
||||
rtx op;
|
||||
enum machine_mode mode;
|
||||
{
|
||||
if (! register_operand (op, mode))
|
||||
if (! reg_operand (op, mode))
|
||||
return 0;
|
||||
if (GET_CODE (op) == SUBREG)
|
||||
op = SUBREG_REG (op);
|
||||
@ -2914,6 +2984,10 @@ src_operand (op, mode)
|
||||
rtx op;
|
||||
enum machine_mode mode;
|
||||
{
|
||||
if (GET_CODE (op) == SUBREG
|
||||
&& mixed_subreg_operand (op, mode))
|
||||
return 0;
|
||||
|
||||
if (REG_P (op))
|
||||
return reg_operand (op, mode);
|
||||
|
||||
|
@ -2655,6 +2655,8 @@ extern int reg_or_const_operand ();
|
||||
|
||||
extern int reg_operand ();
|
||||
|
||||
extern int mixed_subreg_operand ();
|
||||
|
||||
extern int reg_imm_operand ();
|
||||
|
||||
extern int r0r1_reg_operand ();
|
||||
|
@ -449,7 +449,9 @@
|
||||
; 8 loadhf_int
|
||||
; 9 storehf_int
|
||||
; 10 RSQRF
|
||||
|
||||
; 11 loadqf_int
|
||||
; 12 storeqf_int
|
||||
; 22 rptb_init
|
||||
|
||||
;
|
||||
; C4x FUNCTIONAL UNITS
|
||||
@ -2968,6 +2970,98 @@
|
||||
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
|
||||
; spill a register.
|
||||
(define_insn "movqf_noclobber"
|
||||
|
Loading…
Reference in New Issue
Block a user