/* @@@ Should really do something sensible here. */
return 0;
}
+
+/* Store OPERAND to the memory after reload is completed. This means
+ that we can't easilly use assign_stack_local. */
+rtx
+ix86_force_to_memory (mode, operand)
+ enum machine_mode mode;
+ rtx operand;
+{
+ if (!reload_completed)
+ abort ();
+ switch (mode)
+ {
+ case DImode:
+ {
+ rtx operands[2];
+ split_di (&operand, 1, operands, operands+1);
+ emit_insn (
+ gen_rtx_SET (VOIDmode,
+ gen_rtx_MEM (SImode,
+ gen_rtx_PRE_DEC (Pmode,
+ stack_pointer_rtx)),
+ operands[1]));
+ emit_insn (
+ gen_rtx_SET (VOIDmode,
+ gen_rtx_MEM (SImode,
+ gen_rtx_PRE_DEC (Pmode,
+ stack_pointer_rtx)),
+ operands[0]));
+ }
+ break;
+ case HImode:
+ /* It is better to store HImodes as SImodes. */
+ if (!TARGET_PARTIAL_REG_STALL)
+ operand = gen_lowpart (SImode, operand);
+ /* FALLTHRU */
+ case SImode:
+ emit_insn (
+ gen_rtx_SET (VOIDmode,
+ gen_rtx_MEM (GET_MODE (operand),
+ gen_rtx_PRE_DEC (SImode,
+ stack_pointer_rtx)),
+ operand));
+ break;
+ default:
+ abort();
+ }
+ return gen_rtx_MEM (mode, stack_pointer_rtx);
+}
+
+/* Free operand from the memory. */
+void
+ix86_free_from_memory (mode)
+ enum machine_mode mode;
+{
+ /* Use LEA to deallocate stack space. In peephole2 it will be converted
+ to pop or add instruction if registers are available. */
+ emit_insn (gen_rtx_SET (VOIDmode, stack_pointer_rtx,
+ gen_rtx_PLUS (Pmode, stack_pointer_rtx,
+ GEN_INT (mode == DImode
+ ? 8
+ : mode == HImode && TARGET_PARTIAL_REG_STALL
+ ? 2
+ : 4))));
+}
;; %%% Kill these when reload knows how to do it.
(define_split
[(set (match_operand 0 "register_operand" "")
- (float (match_operand:HI 1 "register_operand" "")))]
+ (float (match_operand 1 "register_operand" "")))]
"reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
- [(set (mem:HI (pre_dec:SI (reg:SI 7))) (match_dup 1))
- (set (match_dup 0) (match_dup 2))
- (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 2)))]
- "operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]),
- gen_rtx_MEM (HImode, stack_pointer_rtx));")
-
-(define_split
- [(set (match_operand 0 "register_operand" "")
- (float (match_operand:SI 1 "register_operand" "")))]
- "reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
- [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 1))
- (set (match_dup 0) (match_dup 2))
- (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
- (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
- "operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]),
- gen_rtx_MEM (SImode, stack_pointer_rtx));")
-
-(define_split
- [(set (match_operand 0 "register_operand" "")
- (float (match_operand:DI 1 "nonmemory_operand" "")))]
- "reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
- [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 2))
- (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 1))
- (set (match_dup 0) (match_dup 3))
- (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
- (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])
- (parallel [(set (match_dup 2) (mem:SI (reg:SI 7)))
- (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
- "split_di (operands+1, 1, operands+1, operands+2);
- operands[3] = gen_rtx_FLOAT (GET_MODE (operands[0]),
- gen_rtx_MEM (DImode, stack_pointer_rtx));")
+ [(const_int 0)]
+ "
+{
+ operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
+ operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
+ emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
+ ix86_free_from_memory (GET_MODE (operands[1]));
+ DONE;
+}")
\f
;; Add instructions
(match_operand 2 "register_operand" "")]))]
"TARGET_80387 && reload_completed
&& FLOAT_MODE_P (GET_MODE (operands[0]))"
- [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 1))
- (set (match_dup 0)
- (match_op_dup 3 [(match_dup 4) (match_dup 2)]))
- (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
- (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
- "operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]),
- gen_rtx_MEM (SImode, stack_pointer_rtx));")
+ [(const_int 0)]
+ "
+{
+ operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
+ operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
+ emit_insn (gen_rtx_SET (VOIDmode, operands[0],
+ gen_rtx_fmt_ee (GET_CODE (operands[3]),
+ GET_MODE (operands[3]),
+ operands[4],
+ operands[2])));
+ ix86_free_from_memory (GET_MODE (operands[1]));
+ DONE;
+}")
(define_split
[(set (match_operand 0 "register_operand" "")
(float (match_operand:SI 2 "register_operand" ""))]))]
"TARGET_80387 && reload_completed
&& FLOAT_MODE_P (GET_MODE (operands[0]))"
- [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 2))
- (set (match_dup 0)
- (match_op_dup 3 [(match_dup 1) (match_dup 4)]))
- (parallel [(set (match_dup 2) (mem:SI (reg:SI 7)))
- (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
- "operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]),
- gen_rtx_MEM (SImode, stack_pointer_rtx));")
+ [(const_int 0)]
+ "
+{
+ operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
+ operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
+ emit_insn (gen_rtx_SET (VOIDmode, operands[0],
+ gen_rtx_fmt_ee (GET_CODE (operands[3]),
+ GET_MODE (operands[3]),
+ operands[1],
+ operands[4])));
+ ix86_free_from_memory (GET_MODE (operands[2]));
+ DONE;
+}")
\f
;; FPU special functions.