Commit 9fc777ad by Chao-ying Fu Committed by Chao-ying Fu

mips.c (mips_scalar_mode_supported_p): Declare.

	* config/mips/mips.c (mips_scalar_mode_supported_p): Declare.
	(TARGET_SCALAR_MODE_SUPPORTED_P): Define.
	(mips_emit_compare): Process fixed-point modes.
	(mips_pad_arg_upward): Support fixed-point types.
	(override_options): Allow fixed-point modes in accumulators.
	(mips_pass_by_reference): Pass DQ, UDQ, DA, and UDA modes in registers.
	(mips_vector_mode_supported_p): Support V2HQmode, V2UHQmode, V2HAmode,
	V2UHAmode, V4QQmode, and V4UQQmode when TARGET_DSP.
	(mips_scalar_mode_supported_p): New function to accept fixed-point
	modes if the width is not greater than two BITS_PER_WORD.
	* config/mips/mips.h (SHORT_FRACT_TYPE_SIZE, FRACT_TYPE_SIZE,
	LONG_FRACT_TYPE_SIZE, LONG_LONG_FRACT_TYPE_SIZE,
	SHORT_ACCUM_TYPE_SIZE, ACCUM_TYPE_SIZE, LONG_ACCUM_TYPE_SIZE,
	LONG_LONG_ACCUM_TYPE_SIZE): Define.
	* config/mips/mips.md ("d"): Update mode attribute for fixed-point
	modes.
	("IMODE"): New mode attribute.
	(mips-fixed.md): Include.
	* config/mips/mips-modes.def: Create VECTOR_MODES for FRACT, UFRACT,
	ACCUM, UACCUM.
	* config/mips/mips-fixed.md: New file.

From-SVN: r128360
parent 9ccaf0a6
2007-09-10 Chao-ying Fu <fu@mips.com>
* config/mips/mips.c (mips_scalar_mode_supported_p): Declare.
(TARGET_SCALAR_MODE_SUPPORTED_P): Define.
(mips_emit_compare): Process fixed-point modes.
(mips_pad_arg_upward): Support fixed-point types.
(override_options): Allow fixed-point modes in accumulators.
(mips_pass_by_reference): Pass DQ, UDQ, DA, and UDA modes in registers.
(mips_vector_mode_supported_p): Support V2HQmode, V2UHQmode, V2HAmode,
V2UHAmode, V4QQmode, and V4UQQmode when TARGET_DSP.
(mips_scalar_mode_supported_p): New function to accept fixed-point
modes if the width is not greater than two BITS_PER_WORD.
* config/mips/mips.h (SHORT_FRACT_TYPE_SIZE, FRACT_TYPE_SIZE,
LONG_FRACT_TYPE_SIZE, LONG_LONG_FRACT_TYPE_SIZE,
SHORT_ACCUM_TYPE_SIZE, ACCUM_TYPE_SIZE, LONG_ACCUM_TYPE_SIZE,
LONG_LONG_ACCUM_TYPE_SIZE): Define.
* config/mips/mips.md ("d"): Update mode attribute for fixed-point
modes.
("IMODE"): New mode attribute.
(mips-fixed.md): Include.
* config/mips/mips-modes.def: Create VECTOR_MODES for FRACT, UFRACT,
ACCUM, UACCUM.
* config/mips/mips-fixed.md: New file.
2007-09-11 Ben Elliston <bje@au.ibm.com>
* config/spu/spu.md: Formatting fixes.
;; This file contains MIPS instructions that support fixed-point operations.
;; All supported fixed-point modes
(define_mode_iterator FIXED [(QQ "") (HQ "") (SQ "") (DQ "TARGET_64BIT")
(UQQ "") (UHQ "") (USQ "") (UDQ "TARGET_64BIT")
(HA "") (SA "") (DA "TARGET_64BIT")
(UHA "") (USA "") (UDA "TARGET_64BIT")])
;; For signed add/sub with saturation
(define_mode_iterator ADDSUB [(HQ "") (SQ "") (HA "") (SA "") (V2HQ "")
(V2HA "")])
(define_mode_attr addsubfmt [(HQ "ph") (SQ "w") (HA "ph") (SA "w")
(V2HQ "ph") (V2HA "ph")])
;; For unsigned add/sub with saturation
(define_mode_iterator UADDSUB [(UQQ "TARGET_DSP") (UHQ "TARGET_DSPR2")
(UHA "TARGET_DSPR2") (V4UQQ "TARGET_DSP")
(V2UHQ "TARGET_DSPR2") (V2UHA "TARGET_DSPR2")])
(define_mode_attr uaddsubfmt [(UQQ "qb") (UHQ "ph") (UHA "ph")
(V4UQQ "qb") (V2UHQ "ph") (V2UHA "ph")])
;; For signed multiplication with saturation
(define_mode_iterator MULQ [(V2HQ "TARGET_DSP") (HQ "TARGET_DSP")
(SQ "TARGET_DSPR2")])
(define_mode_attr mulqfmt [(V2HQ "ph") (HQ "ph") (SQ "w")])
(define_insn "add<mode>3"
[(set (match_operand:FIXED 0 "register_operand" "=d")
(plus:FIXED (match_operand:FIXED 1 "register_operand" "d")
(match_operand:FIXED 2 "register_operand" "d")))]
""
"<d>addu\t%0,%1,%2"
[(set_attr "type" "arith")
(set_attr "mode" "<IMODE>")])
(define_insn "usadd<mode>3"
[(parallel
[(set (match_operand:UADDSUB 0 "register_operand" "=d")
(us_plus:UADDSUB (match_operand:UADDSUB 1 "register_operand" "d")
(match_operand:UADDSUB 2 "register_operand" "d")))
(set (reg:CCDSP CCDSP_OU_REGNUM)
(unspec:CCDSP [(match_dup 1) (match_dup 2)] UNSPEC_ADDQ_S))])]
""
"addu_s.<uaddsubfmt>\t%0,%1,%2"
[(set_attr "type" "arith")
(set_attr "mode" "<IMODE>")])
(define_insn "ssadd<mode>3"
[(parallel
[(set (match_operand:ADDSUB 0 "register_operand" "=d")
(ss_plus:ADDSUB (match_operand:ADDSUB 1 "register_operand" "d")
(match_operand:ADDSUB 2 "register_operand" "d")))
(set (reg:CCDSP CCDSP_OU_REGNUM)
(unspec:CCDSP [(match_dup 1) (match_dup 2)] UNSPEC_ADDQ_S))])]
"TARGET_DSP"
"addq_s.<addsubfmt>\t%0,%1,%2"
[(set_attr "type" "arith")
(set_attr "mode" "<IMODE>")])
(define_insn "sub<mode>3"
[(set (match_operand:FIXED 0 "register_operand" "=d")
(minus:FIXED (match_operand:FIXED 1 "register_operand" "d")
(match_operand:FIXED 2 "register_operand" "d")))]
""
"<d>subu\t%0,%1,%2"
[(set_attr "type" "arith")
(set_attr "mode" "<IMODE>")])
(define_insn "ussub<mode>3"
[(parallel
[(set (match_operand:UADDSUB 0 "register_operand" "=d")
(us_minus:UADDSUB (match_operand:UADDSUB 1 "register_operand" "d")
(match_operand:UADDSUB 2 "register_operand" "d")))
(set (reg:CCDSP CCDSP_OU_REGNUM)
(unspec:CCDSP [(match_dup 1) (match_dup 2)] UNSPEC_SUBQ_S))])]
""
"subu_s.<uaddsubfmt>\t%0,%1,%2"
[(set_attr "type" "arith")
(set_attr "mode" "<IMODE>")])
(define_insn "sssub<mode>3"
[(parallel
[(set (match_operand:ADDSUB 0 "register_operand" "=d")
(ss_minus:ADDSUB (match_operand:ADDSUB 1 "register_operand" "d")
(match_operand:ADDSUB 2 "register_operand" "d")))
(set (reg:CCDSP CCDSP_OU_REGNUM)
(unspec:CCDSP [(match_dup 1) (match_dup 2)] UNSPEC_SUBQ_S))])]
"TARGET_DSP"
"subq_s.<addsubfmt>\t%0,%1,%2"
[(set_attr "type" "arith")
(set_attr "mode" "<IMODE>")])
(define_insn "ssmul<mode>3"
[(parallel
[(set (match_operand:MULQ 0 "register_operand" "=d")
(ss_mult:MULQ (match_operand:MULQ 1 "register_operand" "d")
(match_operand:MULQ 2 "register_operand" "d")))
(set (reg:CCDSP CCDSP_OU_REGNUM)
(unspec:CCDSP [(match_dup 1) (match_dup 2)] UNSPEC_MULQ_RS_PH))
(clobber (match_scratch:DI 3 "=x"))])]
""
"mulq_rs.<mulqfmt>\t%0,%1,%2"
[(set_attr "type" "imul3")
(set_attr "mode" "<IMODE>")])
(define_insn "ssmaddsqdq4"
[(parallel
[(set (match_operand:DQ 0 "register_operand" "=a")
(ss_plus:DQ
(ss_mult:DQ (sat_fract:DQ (match_operand:SQ 1
"register_operand" "d"))
(sat_fract:DQ (match_operand:SQ 2
"register_operand" "d")))
(match_operand:DQ 3 "register_operand" "0")))
(set (reg:CCDSP CCDSP_OU_REGNUM)
(unspec:CCDSP [(match_dup 1) (match_dup 2) (match_dup 3)]
UNSPEC_DPAQ_SA_L_W))])]
"TARGET_DSP && !TARGET_64BIT"
"dpaq_sa.l.w\t%q0,%1,%2"
[(set_attr "type" "imadd")
(set_attr "mode" "SI")])
(define_insn "ssmsubsqdq4"
[(parallel
[(set (match_operand:DQ 0 "register_operand" "=a")
(ss_minus:DQ
(match_operand:DQ 3 "register_operand" "0")
(ss_mult:DQ (sat_fract:DQ (match_operand:SQ 1
"register_operand" "d"))
(sat_fract:DQ (match_operand:SQ 2
"register_operand" "d")))))
(set (reg:CCDSP CCDSP_OU_REGNUM)
(unspec:CCDSP [(match_dup 1) (match_dup 2) (match_dup 3)]
UNSPEC_DPSQ_SA_L_W))])]
"TARGET_DSP && !TARGET_64BIT"
"dpsq_sa.l.w\t%q0,%1,%2"
[(set_attr "type" "imadd")
(set_attr "mode" "SI")])
......@@ -29,6 +29,11 @@ FLOAT_MODE (TF, 16, mips_quad_format);
VECTOR_MODES (FLOAT, 8); /* V4HF V2SF */
VECTOR_MODES (INT, 4); /* V4QI V2HI */
VECTOR_MODES (FRACT, 4); /* V4QQ V2HQ */
VECTOR_MODES (UFRACT, 4); /* V4UQQ V2UHQ */
VECTOR_MODES (ACCUM, 4); /* V2HA */
VECTOR_MODES (UACCUM, 4); /* V2UHA */
/* Paired single comparison instructions use 2 or 4 CC. */
CC_MODE (CCV2);
ADJUST_BYTESIZE (CCV2, 8);
......
......@@ -408,6 +408,7 @@ static bool mips_callee_copies (CUMULATIVE_ARGS *, enum machine_mode mode,
static int mips_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode mode,
tree, bool);
static bool mips_valid_pointer_mode (enum machine_mode);
static bool mips_scalar_mode_supported_p (enum machine_mode);
static bool mips_vector_mode_supported_p (enum machine_mode);
static rtx mips_prepare_builtin_arg (enum insn_code, unsigned int, tree, unsigned int);
static rtx mips_prepare_builtin_target (enum insn_code, unsigned int, rtx);
......@@ -1329,6 +1330,9 @@ static const unsigned char mips16e_save_restore_regs[] = {
#undef TARGET_VECTOR_MODE_SUPPORTED_P
#define TARGET_VECTOR_MODE_SUPPORTED_P mips_vector_mode_supported_p
#undef TARGET_SCALAR_MODE_SUPPORTED_P
#define TARGET_SCALAR_MODE_SUPPORTED_P mips_scalar_mode_supported_p
#undef TARGET_INIT_BUILTINS
#define TARGET_INIT_BUILTINS mips_init_builtins
#undef TARGET_EXPAND_BUILTIN
......@@ -3626,6 +3630,13 @@ mips_emit_compare (enum rtx_code *code, rtx *op0, rtx *op1, bool need_eq_ne_p)
*code = (invert ? EQ : NE);
}
}
else if (ALL_FIXED_POINT_MODE_P (GET_MODE (cmp_operands[0])))
{
*op0 = gen_rtx_REG (CCDSPmode, CCDSP_CC_REGNUM);
mips_emit_binary (*code, *op0, cmp_operands[0], cmp_operands[1]);
*code = NE;
*op1 = const0_rtx;
}
else
{
enum rtx_code cmp_code;
......@@ -4470,8 +4481,11 @@ mips_pad_arg_upward (enum machine_mode mode, const_tree type)
/* Otherwise, integral types are padded downward: the last byte of a
stack argument is passed in the last byte of the stack slot. */
if (type != 0
? INTEGRAL_TYPE_P (type) || POINTER_TYPE_P (type)
: GET_MODE_CLASS (mode) == MODE_INT)
? (INTEGRAL_TYPE_P (type)
|| POINTER_TYPE_P (type)
|| FIXED_POINT_TYPE_P (type))
: (GET_MODE_CLASS (mode) == MODE_INT
|| ALL_SCALAR_FIXED_POINT_MODE_P (mode)))
return false;
/* Big-endian o64 pads floating-point arguments downward. */
......@@ -5737,7 +5751,7 @@ override_options (void)
|| (ISA_HAS_8CC && mode == TFmode)));
else if (ACC_REG_P (regno))
temp = (INTEGRAL_MODE_P (mode)
temp = ((INTEGRAL_MODE_P (mode) || ALL_FIXED_POINT_MODE_P (mode))
&& size <= UNITS_PER_WORD * 2
&& (size <= UNITS_PER_WORD
|| regno == MD_REG_FIRST
......@@ -8749,7 +8763,9 @@ mips_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
int size;
/* ??? How should SCmode be handled? */
if (mode == DImode || mode == DFmode)
if (mode == DImode || mode == DFmode
|| mode == DQmode || mode == UDQmode
|| mode == DAmode || mode == UDAmode)
return 0;
size = type ? int_size_in_bytes (type) : GET_MODE_SIZE (mode);
......@@ -9011,12 +9027,30 @@ mips_vector_mode_supported_p (enum machine_mode mode)
case V2HImode:
case V4QImode:
case V2HQmode:
case V2UHQmode:
case V2HAmode:
case V2UHAmode:
case V4QQmode:
case V4UQQmode:
return TARGET_DSP;
default:
return false;
}
}
/* Implement TARGET_SCALAR_MODE_SUPPORTED_P. */
static bool
mips_scalar_mode_supported_p (enum machine_mode mode)
{
if (ALL_FIXED_POINT_MODE_P (mode)
&& GET_MODE_PRECISION (mode) <= 2 * BITS_PER_WORD)
return true;
return default_scalar_mode_supported_p (mode);
}
/* If we can access small data directly (using gp-relative relocation
operators) return the small data pointer, otherwise return null.
......
......@@ -1189,6 +1189,19 @@ extern enum mips_code_readable_setting mips_code_readable;
#define DOUBLE_TYPE_SIZE 64
#define LONG_DOUBLE_TYPE_SIZE (TARGET_NEWABI ? 128 : 64)
/* Define the sizes of fixed-point types. */
#define SHORT_FRACT_TYPE_SIZE 8
#define FRACT_TYPE_SIZE 16
#define LONG_FRACT_TYPE_SIZE 32
#define LONG_LONG_FRACT_TYPE_SIZE 64
#define SHORT_ACCUM_TYPE_SIZE 16
#define ACCUM_TYPE_SIZE 32
#define LONG_ACCUM_TYPE_SIZE 64
/* FIXME. LONG_LONG_ACCUM_TYPE_SIZE should be 128 bits, but GCC
doesn't support 128-bit integers for MIPS32 currently. */
#define LONG_LONG_ACCUM_TYPE_SIZE (TARGET_64BIT ? 128 : 64)
/* long double is not a fixed mode, but the idea is that, if we
support long double, we also want a 128-bit integer type. */
#define MAX_FIXED_MODE_SIZE LONG_DOUBLE_TYPE_SIZE
......
......@@ -497,7 +497,11 @@
;; In GPR templates, a string like "<d>subu" will expand to "subu" in the
;; 32-bit version and "dsubu" in the 64-bit version.
(define_mode_attr d [(SI "") (DI "d")])
(define_mode_attr d [(SI "") (DI "d")
(QQ "") (HQ "") (SQ "") (DQ "d")
(UQQ "") (UHQ "") (USQ "") (UDQ "d")
(HA "") (SA "") (DA "d")
(UHA "") (USA "") (UDA "d")])
;; This attribute gives the length suffix for a sign- or zero-extension
;; instruction.
......@@ -530,6 +534,15 @@
;; floating-point mode.
(define_mode_attr UNITMODE [(SF "SF") (DF "DF") (V2SF "SF")])
;; This attribute gives the integer mode that has the same size as a
;; fixed-point mode.
(define_mode_attr IMODE [(QQ "QI") (HQ "HI") (SQ "SI") (DQ "DI")
(UQQ "QI") (UHQ "HI") (USQ "SI") (UDQ "DI")
(HA "HI") (SA "SI") (DA "DI")
(UHA "HI") (USA "SI") (UDA "DI")
(V4UQQ "SI") (V2UHQ "SI") (V2UHA "SI")
(V2HQ "SI") (V2HA "SI")])
;; This attribute works around the early SB-1 rev2 core "F2" erratum:
;;
;; In certain cases, div.s and div.ps may have a rounding error
......@@ -6009,3 +6022,6 @@
; The MIPS DSP REV 2 Instructions.
(include "mips-dspr2.md")
; MIPS fixed-point instructions.
(include "mips-fixed.md")
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment