+2008-12-21 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * config/mips/mips-dsp.md (mips_lbux): Turn into a define_expand,
+ changing operand 1 to a pmode_register_operand.
+ (mips_lhx, mips_lwx): Likewise.
+ (mips_lbux_<mode>, mips_lhx_<mode>, mips_lwx_<mode>): New patterns.
+ * config/mips/mips.c (mips_prepare_builtin_arg): Get the mode of
+ the value from the argument expression.
+
2008-12-21 Jan Hubicka <jh@suse.cz>
Kai Tietz <kai.tietz@onevision.com>
;; Table 2-7. MIPS DSP ASE Instructions: Indexed-Load
;; L*X
-(define_insn "mips_lbux"
+(define_expand "mips_lbux"
+ [(match_operand:SI 0 "register_operand")
+ (match_operand 1 "pmode_register_operand")
+ (match_operand:SI 2 "register_operand")]
+ "ISA_HAS_DSP"
+{
+ operands[2] = convert_to_mode (Pmode, operands[2], false);
+ if (Pmode == SImode)
+ emit_insn (gen_mips_lbux_si (operands[0], operands[1], operands[2]));
+ else
+ emit_insn (gen_mips_lbux_di (operands[0], operands[1], operands[2]));
+ DONE;
+})
+
+(define_insn "mips_lbux_<mode>"
[(set (match_operand:SI 0 "register_operand" "=d")
- (zero_extend:SI (mem:QI (plus:SI (match_operand:SI 1
- "register_operand" "d")
- (match_operand:SI 2
- "register_operand" "d")))))]
+ (zero_extend:SI
+ (mem:QI (plus:P (match_operand:P 1 "register_operand" "d")
+ (match_operand:P 2 "register_operand" "d")))))]
"ISA_HAS_DSP"
"lbux\t%0,%2(%1)"
[(set_attr "type" "load")
(set_attr "mode" "SI")])
-(define_insn "mips_lhx"
+(define_expand "mips_lhx"
+ [(match_operand:SI 0 "register_operand")
+ (match_operand 1 "pmode_register_operand")
+ (match_operand:SI 2 "register_operand")]
+ "ISA_HAS_DSP"
+{
+ operands[2] = convert_to_mode (Pmode, operands[2], false);
+ if (Pmode == SImode)
+ emit_insn (gen_mips_lhx_si (operands[0], operands[1], operands[2]));
+ else
+ emit_insn (gen_mips_lhx_di (operands[0], operands[1], operands[2]));
+ DONE;
+})
+
+(define_insn "mips_lhx_<mode>"
[(set (match_operand:SI 0 "register_operand" "=d")
- (sign_extend:SI (mem:HI (plus:SI (match_operand:SI 1
- "register_operand" "d")
- (match_operand:SI 2
- "register_operand" "d")))))]
+ (zero_extend:SI
+ (mem:HI (plus:P (match_operand:P 1 "register_operand" "d")
+ (match_operand:P 2 "register_operand" "d")))))]
"ISA_HAS_DSP"
"lhx\t%0,%2(%1)"
[(set_attr "type" "load")
(set_attr "mode" "SI")])
-(define_insn "mips_lwx"
+(define_expand "mips_lwx"
+ [(match_operand:SI 0 "register_operand")
+ (match_operand 1 "pmode_register_operand")
+ (match_operand:SI 2 "register_operand")]
+ "ISA_HAS_DSP"
+{
+ operands[2] = convert_to_mode (Pmode, operands[2], false);
+ if (Pmode == SImode)
+ emit_insn (gen_mips_lwx_si (operands[0], operands[1], operands[2]));
+ else
+ emit_insn (gen_mips_lwx_di (operands[0], operands[1], operands[2]));
+ DONE;
+})
+
+(define_insn "mips_lwx_<mode>"
[(set (match_operand:SI 0 "register_operand" "=d")
- (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "d")
- (match_operand:SI 2 "register_operand" "d"))))]
+ (mem:SI (plus:P (match_operand:P 1 "register_operand" "d")
+ (match_operand:P 2 "register_operand" "d"))))]
"ISA_HAS_DSP"
"lwx\t%0,%2(%1)"
[(set_attr "type" "load")
mips_prepare_builtin_arg (enum insn_code icode,
unsigned int opno, tree exp, unsigned int argno)
{
+ tree arg;
rtx value;
enum machine_mode mode;
- value = expand_normal (CALL_EXPR_ARG (exp, argno));
+ arg = CALL_EXPR_ARG (exp, argno);
+ value = expand_normal (arg);
mode = insn_data[icode].operand[opno].mode;
if (!insn_data[icode].operand[opno].predicate (value, mode))
{
- /* Cope with address operands, where MODE is not the mode of
- VALUE itself. */
- if (GET_MODE (value) == VOIDmode)
- value = copy_to_mode_reg (mode, value);
- else
- value = copy_to_reg (value);
+ /* We need to get the mode from ARG for two reasons:
+
+ - to cope with address operands, where MODE is the mode of the
+ memory, rather than of VALUE itself.
+
+ - to cope with special predicates like pmode_register_operand,
+ where MODE is VOIDmode. */
+ value = copy_to_mode_reg (TYPE_MODE (TREE_TYPE (arg)), value);
/* Check the predicate again. */
if (!insn_data[icode].operand[opno].predicate (value, mode))