fix stdcall: implement call_pop instruction

This commit is contained in:
Wolfgang Thaller 2012-04-15 03:32:29 +02:00
parent a609de329b
commit 4282f24fb4
2 changed files with 87 additions and 2 deletions

View File

@ -13347,10 +13347,10 @@ distribute_notes (rtx notes, rtx from_insn, rtx i3, rtx i2, rtx elim_i2,
old_size = fixup_args_size_notes (PREV_INSN (i3), i3, args_size);
/* emit_call_1 adds for !ACCUMULATE_OUTGOING_ARGS
REG_ARGS_SIZE note to all noreturn calls, allow that here. */
/* gcc_assert (old_size != args_size
gcc_assert (old_size != args_size
|| (CALL_P (i3)
&& !ACCUMULATE_OUTGOING_ARGS
&& find_reg_note (i3, REG_NORETURN, NULL_RTX)));*/
&& find_reg_note (i3, REG_NORETURN, NULL_RTX)));
}
break;

View File

@ -7070,6 +7070,41 @@
operands[1] = m68k_legitimize_call_address (operands[1]);
})
(define_expand "call_pop"
[(parallel [(call (match_operand:QI 0 "memory_operand" "")
(match_operand:SI 1 "general_operand" ""))
(set (reg:SI SP_REG)
(plus:SI (reg:SI SP_REG)
(match_operand:SI 3 "" "")))])]
""
{
operands[0] = m68k_legitimize_call_address (operands[0]);
})
(define_expand "call_value_pop"
[(parallel [(set (match_operand 0 "" "")
(call (match_operand:QI 1 "memory_operand" "")
(match_operand:SI 2 "general_operand" "")))
(set (reg:SI SP_REG)
(plus:SI (reg:SI SP_REG)
(match_operand:SI 4 "" "")))])]
""
{
operands[1] = m68k_legitimize_call_address (operands[1]);
})
(define_insn "*call_pop"
[(call (mem:QI (match_operand:SI 0 "call_operand" "a,W"))
(match_operand:SI 1 "general_operand" "g,g"))
(set (reg:SI SP_REG)
(plus:SI (reg:SI SP_REG)
(match_operand:SI 2 "" "")))]
;; Operand 1 not really used on the m68000.
"!SIBLING_CALL_P (insn)"
{
return output_call (operands[0]);
}
[(set_attr "type" "jsr")])
(define_insn "*non_symbolic_call_value"
[(set (match_operand 0 "" "=rf,rf")
(call (mem:QI (match_operand:SI 1 "non_symbolic_call_operand" "a,W"))
@ -7108,6 +7143,56 @@
[(set_attr "type" "bsr")
(set_attr "opx" "1")])
(define_insn "*non_symbolic_call_value_pop"
[(set (match_operand 0 "" "=rf,rf")
(call (mem:QI (match_operand:SI 1 "non_symbolic_call_operand" "a,W"))
(match_operand:SI 2 "general_operand" "g,g")))
(set (reg:SI SP_REG)
(plus:SI (reg:SI SP_REG)
(match_operand:SI 3 "" "")))]
;; Operand 2 not really used on the m68000.
"!SIBLING_CALL_P (insn)"
"jsr %a1"
[(set_attr "type" "jsr")
(set_attr "opx" "1")])
(define_insn "*symbolic_call_value_pop_jsr"
[(set (match_operand 0 "" "=rf,rf")
(call (mem:QI (match_operand:SI 1 "symbolic_operand" "a,W"))
(match_operand:SI 2 "general_operand" "g,g")))
(set (reg:SI SP_REG)
(plus:SI (reg:SI SP_REG)
(match_operand:SI 3 "" "")))]
;; Operand 2 not really used on the m68000.
"!SIBLING_CALL_P (insn) && m68k_symbolic_call_var == M68K_SYMBOLIC_CALL_JSR"
{
operands[0] = operands[1];
return m68k_symbolic_call;
}
[(set_attr "type" "jsr")
(set_attr "opx" "1")])
(define_insn "*symbolic_call_value_pop_bsr"
[(set (match_operand 0 "" "=rf,rf")
(call (mem:QI (match_operand:SI 1 "symbolic_operand" "a,W"))
(match_operand:SI 2 "general_operand" "g,g")))
(set (reg:SI SP_REG)
(plus:SI (reg:SI SP_REG)
(match_operand:SI 3 "" "")))]
;; Operand 2 not really used on the m68000.
"!SIBLING_CALL_P (insn)
&& (m68k_symbolic_call_var == M68K_SYMBOLIC_CALL_BSR_C
|| m68k_symbolic_call_var == M68K_SYMBOLIC_CALL_BSR_P)"
{
operands[0] = operands[1];
return m68k_symbolic_call;
}
[(set_attr "type" "bsr")
(set_attr "opx" "1")])
;; Call subroutine returning any type.
(define_expand "untyped_call"