aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/mips/mips.c
diff options
context:
space:
mode:
authorChao-ying Fu <fu@mips.com>2007-09-11 01:04:08 +0000
committerChao-ying Fu <chaoyingfu@gcc.gnu.org>2007-09-11 01:04:08 +0000
commit9fc777ad2561e542ef0eec9d94ee8cb5edc68554 (patch)
tree90489292cc9aae88f88ecd159e05429ec37d914c /gcc/config/mips/mips.c
parent9ccaf0a6285b6b9d346cb0e3b8593ab89ef8fd46 (diff)
downloadgcc-9fc777ad2561e542ef0eec9d94ee8cb5edc68554.zip
gcc-9fc777ad2561e542ef0eec9d94ee8cb5edc68554.tar.gz
gcc-9fc777ad2561e542ef0eec9d94ee8cb5edc68554.tar.bz2
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
Diffstat (limited to 'gcc/config/mips/mips.c')
-rw-r--r--gcc/config/mips/mips.c42
1 files changed, 38 insertions, 4 deletions
diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index 4a180da..14f0de2 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -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.