+2006-12-04 Trevor Smigiel <trevor_smigiel@playstation.sony.com>
+
+ * config/spu/spu-protos.c (spu_split_address): Add.
+ * config/spu/spu.c (spu_split_address): Add.
+ (print_operand): Handle HIGH.
+ (spu_legitimate_address): Don't test for aligned CONST.
+ (spu_expand_mov): Don't split addresses here.
+ * config/spu/constraints.md (A): Don't test legitimate_const.
+ * config/spu/spu.md: Add split of movsi patterns for PIC mode.
+ (ceq_di): Use correct predicates.
+
2006-12-04 Eric Christopher <echristo@apple.com>
* config/darwin.h: Update copyright notice.
"An immediate which can be loaded with the il/ila/ilh/ilhu instructions. const_int is treated as a 32 bit value."
(ior (and (match_code "const_int,const_double,const_vector")
(match_test "immediate_load_p (op, SImode)"))
- (and (match_test "!TARGET_LARGE_MEM && !flag_pic")
- (ior (match_code "symbol_ref,label_ref")
- (and (match_code "const")
- (match_test "legitimate_const (op, 0)"))))))
+ (match_code "symbol_ref,label_ref,high,const")))
(define_constraint "B"
"An immediate for arithmetic instructions (e.g., ai, ceqi). const_int is treated as a 32 bit value."
}
else if (xcode == SYMBOL_REF || xcode == LABEL_REF || xcode == CONST)
fprintf (file, "a");
+ else if (xcode == HIGH)
+ fprintf (file, "hu");
else
gcc_unreachable ();
return;
}
else if (xcode == CONST || xcode == SYMBOL_REF || xcode == LABEL_REF)
output_addr_const (file, x);
+ else if (xcode == HIGH)
+ {
+ output_addr_const (file, XEXP (x, 0));
+ fprintf (file, "@h");
+ }
else
gcc_unreachable ();
return;
return pic_reg;
}
+/* Split constant addresses to handle cases that are too large. Also, add in
+ the pic register when in PIC mode. */
+void
+spu_split_address (rtx * ops)
+{
+ if (TARGET_LARGE_MEM
+ || (GET_CODE (ops[1]) == CONST && !legitimate_const (ops[1], 0)))
+ {
+ emit_insn (gen_high (ops[0], ops[1]));
+ emit_insn (gen_low (ops[0], ops[0], ops[1]));
+ }
+ else if (flag_pic)
+ emit_insn (gen_pic (ops[0], ops[1]));
+ if (flag_pic)
+ {
+ rtx pic_reg = get_pic_reg ();
+ emit_insn (gen_addsi3 (ops[0], ops[0], pic_reg));
+ current_function_uses_pic_offset_table = 1;
+ }
+}
+
/* SAVING is TRUE when we are generating the actual load and store
instructions for REGNO. When determining the size of the stack
needed for saving register we must allocate enough space for the
return !TARGET_LARGE_MEM;
case CONST:
- return !TARGET_LARGE_MEM && legitimate_const (x, 1);
+ return !TARGET_LARGE_MEM && legitimate_const (x, 0);
case CONST_INT:
return INTVAL (x) >= 0 && INTVAL (x) <= 0x3ffff;
emit_insn (gen_rtx_SET (VOIDmode, to, gen_rtx_IOR (mode, to, lo)));
return 1;
}
- if ((GET_CODE (ops[1]) == CONST
- && !legitimate_const (ops[1], 0))
- || (TARGET_LARGE_MEM
- && (GET_CODE (ops[1]) == CONST
- || GET_CODE (ops[1]) == SYMBOL_REF
- || GET_CODE (ops[1]) == LABEL_REF)))
- {
- emit_insn (gen_high (ops[0], ops[1]));
- emit_insn (gen_low (ops[0], ops[0], ops[1]));
- if (flag_pic)
- {
- rtx pic_reg = get_pic_reg ();
- emit_insn (gen_addsi3 (ops[0], ops[0], pic_reg));
- current_function_uses_pic_offset_table = 1;
- }
- return 1;
- }
- if (flag_pic
- && (GET_CODE (ops[1]) == SYMBOL_REF
- || GET_CODE (ops[1]) == LABEL_REF
- || GET_CODE (ops[1]) == CONST))
- {
- rtx pic_reg = get_pic_reg ();
- emit_insn (gen_pic (ops[0], ops[1]));
- emit_insn (gen_addsi3 (ops[0], ops[0], pic_reg));
- current_function_uses_pic_offset_table = 1;
- return 1;
- }
return 0;
}
else
DONE;
})
+(define_split
+ [(set (match_operand:SI 0 "spu_reg_operand" "=r")
+ (match_operand:SI 1 "immediate_operand" "s"))]
+
+ "(flag_pic || TARGET_LARGE_MEM
+ || (GET_CODE (operands[1]) == CONST
+ && !legitimate_const (operands[1], 0)))
+ && (reload_in_progress || reload_completed)
+ && (GET_CODE (operands[1]) == CONST
+ || GET_CODE (operands[1]) == SYMBOL_REF
+ || GET_CODE (operands[1]) == LABEL_REF)"
+ [(parallel
+ [(set (match_dup:SI 0)
+ (match_dup:SI 1))
+ (use (const_int 0))])
+ (set (match_dup:SI 0)
+ (plus:SI (match_dup:SI 0)
+ (match_dup:SI 2)))]
+ {
+ spu_split_address(operands);
+ DONE;
+ })
+
(define_insn "pic"
[(set (match_operand:SI 0 "spu_reg_operand" "=r")
(match_operand:SI 1 "immediate_operand" "s"))
ceq<bh>i\t%0,%1,%2")
(define_insn_and_split "ceq_di"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (eq:SI (match_operand:DI 1 "register_operand" "r")
- (match_operand:DI 2 "register_operand" "r")))]
+ [(set (match_operand:SI 0 "spu_reg_operand" "=r")
+ (eq:SI (match_operand:DI 1 "spu_reg_operand" "r")
+ (match_operand:DI 2 "spu_reg_operand" "r")))]
""
"#"
"reload_completed"