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>
|
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.
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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 ();
|
||||||
|
@ -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"
|
||||||
|
Loading…
Reference in New Issue
Block a user