call-clobbered registers? We lose this if it is a JUMP_INSN.
Why cannot we have delay slots filled if it were a CALL? */
- if (! TARGET_V9 && INTVAL (operands[3]) > 0)
+ if (! TARGET_V9 && INTVAL (operands[3]) != 0)
emit_jump_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (3,
gen_rtx (SET, VOIDmode, pc_rtx,
XEXP (operands[0], 0)),
nregs_rtx = const0_rtx;
#endif
- if (! TARGET_V9 && INTVAL (operands[3]) > 0)
+ if (! TARGET_V9 && INTVAL (operands[3]) != 0)
emit_call_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (3,
gen_rtx (CALL, VOIDmode, fn_rtx, nregs_rtx),
operands[3],
}"
[(set_attr "type" "call_no_delay_slot")])
+;; This is a call that may want a structure value. This is used for
+;; untyped_calls.
+(define_insn ""
+ [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
+ (match_operand 1 "" ""))
+ (match_operand 2 "immediate_operand" "")
+ (clobber (reg:SI 15))]
+ ;;- Do not use operand 1 for most machines.
+ "! TARGET_V9 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
+ "*
+{
+ return \"call %a0,%1\;nop\;nop\";
+}"
+ [(set_attr "type" "call_no_delay_slot")])
+
+;; This is a call that wants a structure value.
+(define_insn ""
+ [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
+ (match_operand 1 "" ""))
+ (match_operand 2 "immediate_operand" "")
+ (clobber (reg:SI 15))]
+ ;;- Do not use operand 1 for most machines.
+ "! TARGET_V9 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
+ "*
+{
+ return \"call %a0,%1\;nop\;nop\";
+}"
+ [(set_attr "type" "call_no_delay_slot")])
+
(define_expand "call_value"
;; Note that this expression is not used for generating RTL.
;; All the RTL is generated explicitly below.
[(set_attr "type" "call")])
(define_expand "untyped_call"
- [(parallel [(call (match_operand:SI 0 "call_operand" "")
+ [(parallel [(call (match_operand 0 "" "")
(const_int 0))
- (match_operand:BLK 1 "memory_operand" "")
- (match_operand 2 "" "")
-;; ??? v9: mode is wrong here.
- (clobber (reg:SI 15))])]
+ (match_operand 1 "" "")
+ (match_operand 2 "" "")])]
""
"
{
- operands[1] = change_address (operands[1], DImode, XEXP (operands[1], 0));
-}")
-
-;; Make a call followed by two nops in case the function being called
-;; returns a structure value and expects to skip an unimp instruction.
+ int i;
-(define_insn ""
- [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
- (const_int 0))
- (match_operand:DI 1 "memory_operand" "o")
- (match_operand 2 "" "")
- (clobber (reg:SI 15))]
- "! TARGET_V9"
- "*
-{
- operands[2] = adj_offsettable_operand (operands[1], 8);
- return \"call %a0,0\;nop\;nop\;std %%o0,%1\;std %%f0,%2\";
-}"
- [(set_attr "type" "multi")])
+ /* Pass constm1 to indicate that it may expect a structure value, but
+ we don't know what size it is. */
+ emit_call_insn (gen_call (operands[0], const0_rtx, NULL, constm1_rtx));
-;; Make a call followed by two nops in case the function being called
-;; returns a structure value and expects to skip an unimp instruction.
+ for (i = 0; i < XVECLEN (operands[2], 0); i++)
+ {
+ rtx set = XVECEXP (operands[2], 0, i);
+ emit_move_insn (SET_DEST (set), SET_SRC (set));
+ }
-(define_insn ""
- [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
- (const_int 0))
- (match_operand:DI 1 "memory_operand" "o")
- (match_operand 2 "" "")
- (clobber (reg:SI 15))]
- ""
- "*
-{
- operands[2] = adj_offsettable_operand (operands[1], 8);
- return \"call %a0,0\;nop\;nop\;std %%o0,%1\;std %%f0,%2\";
-}"
- [(set_attr "type" "multi")])
+ /* The optimizer does not know that the call sets the function value
+ registers we stored in the result block. We avoid problems by
+ claiming that all hard registers are used and clobbered at this
+ point. */
+ emit_insn (gen_blockage ());
-;; V9 version of untyped_call.
+ DONE;
+}")
-(define_insn ""
- [(call (mem:SI (match_operand:DI 0 "address_operand" "p"))
- (const_int 0))
- (match_operand:DI 1 "memory_operand" "o")
- (match_operand 2 "" "")
-;; ??? Mode is wrong here, but it must match the define_expand.
- (clobber (reg:SI 15))]
- "TARGET_V9"
- "*
-{
- operands[2] = adj_offsettable_operand (operands[1], 8);
- return \"call %a0,0\;nop\;stx %%o0,%1\;stq %%f0,%2\";
-}"
- [(set_attr "type" "multi")])
+;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
+;; all of memory. This blocks insns from being moved across this point.
-(define_insn ""
- [(call (mem:SI (match_operand:DI 0 "symbolic_operand" "s"))
- (const_int 0))
- (match_operand:DI 1 "memory_operand" "o")
- (match_operand 2 "" "")
-;; ??? Mode is wrong here, but it must match the define_expand.
- (clobber (reg:SI 15))]
- "TARGET_V9"
- "*
-{
- operands[2] = adj_offsettable_operand (operands[1], 8);
- return \"call %a0,0\;nop\;stx %%o0,%1\;stq %%f0,%2\";
-}"
- [(set_attr "type" "multi")])
+(define_insn "blockage"
+ [(unspec_volatile [(const_int 0)] 0)]
+ ""
+ "")
;; Prepare to return any type including a structure value.
;; Special trap insn to flush register windows.
(define_insn "flush_register_windows"
- [(unspec_volatile [(const_int 0)] 0)]
+ [(unspec_volatile [(const_int 0)] 1)]
""
"* return TARGET_V9 ? \"flushw\" : \"ta 3\";"
[(set_attr "type" "misc")])
(define_insn "goto_handler_and_restore"
- [(unspec_volatile [(const_int 0)] 1)]
+ [(unspec_volatile [(const_int 0)] 2)]
""
"jmp %%o0+0\;restore"
[(set_attr "type" "misc")
;; Special pattern for the FLUSH instruction.
(define_insn "flush"
- [(unspec_volatile [(match_operand 0 "" "")] 2)]
+ [(unspec_volatile [(match_operand 0 "" "")] 3)]
""
"* return TARGET_V9 ? \"flush %a0\" : \"iflush %a0\";"
[(set_attr "type" "misc")])