On Wed, Mar 7, 2012 at 1:28 AM, Uros Bizjak <[email protected]> wrote:
> On Tue, Mar 6, 2012 at 9:57 PM, H.J. Lu <[email protected]> wrote:
>>>> (define_insn "*call"
>>>> - [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zw"))
>>>> + [(call (mem:QI (match_operand:C 0 "call_insn_operand" "<c>zw"))
>>>> (match_operand 1 "" ""))]
>>>> - "!SIBLING_CALL_P (insn)"
>>>> + "!SIBLING_CALL_P (insn)
>>>> + && (GET_CODE (operands[0]) == SYMBOL_REF
>>>> + || GET_MODE (operands[0]) == word_mode)"
>>>
>>> There are enough copies of this extra constraint that I wonder
>>> if it simply ought to be folded into call_insn_operand.
>>>
>>> Which would need to be changed to define_special_predicate,
>>> since you'd be doing your own mode checking.
>>>
>>> Probably similar changes to sibcall_insn_operand.
>>
>> Here is the updated patch. I changed constant_call_address_operand
>> and call_register_no_elim_operand to use define_special_predicate.
>> OK for trunk?
>
> Please do not complicate matters that much. Just stick word_mode
> overrides for register operands in predicates.md, like in attached
> patch. These changed predicates now allow registers only in word_mode
> (and VOIDmode).
>
> You can now remove all new mode iterators and leave call patterns untouched.
>
> @@ -22940,14 +22940,18 @@ ix86_expand_call (rtx retval, rtx fnaddr,
> rtx callarg1,
> && GET_CODE (XEXP (fnaddr, 0)) == SYMBOL_REF
> && !local_symbolic_operand (XEXP (fnaddr, 0), VOIDmode))
> fnaddr = gen_rtx_MEM (QImode, construct_plt_address (XEXP (fnaddr, 0)));
> - else if (sibcall
> - ? !sibcall_insn_operand (XEXP (fnaddr, 0), Pmode)
> - : !call_insn_operand (XEXP (fnaddr, 0), Pmode))
> + else if (!(constant_call_address_operand (XEXP (fnaddr, 0), Pmode)
> + || call_register_no_elim_operand (XEXP (fnaddr, 0),
> + word_mode)
> + || (!sibcall
> + && !TARGET_X32
> + && memory_operand (XEXP (fnaddr, 0), word_mode))))
> {
> fnaddr = XEXP (fnaddr, 0);
> - if (GET_MODE (fnaddr) != Pmode)
> - fnaddr = convert_to_mode (Pmode, fnaddr, 1);
> - fnaddr = gen_rtx_MEM (QImode, copy_to_mode_reg (Pmode, fnaddr));
> + if (GET_MODE (fnaddr) != word_mode)
> + fnaddr = convert_to_mode (word_mode, fnaddr, 1);
> + fnaddr = gen_rtx_MEM (QImode,
> + copy_to_mode_reg (word_mode, fnaddr));
> }
>
> vec_len = 0;
>
> Please update the above part. It looks you don't even have to change
> condition with new predicates. Basically, you should only convert the
> address to word_mode instead of Pmode.
>
> + if (TARGET_X32)
> + operands[0] = convert_memory_address (word_mode, operands[0]);
>
> This addition to indirect_jump and tablejump should be the only
> change, needed in i386.md now. Please write the condition
>
> if (Pmode != word_mode)
>
> for consistency.
>
> BTW: The attached patch was bootstrapped and regression tested on
> x86_64-pc-linux-gnu {,-m32}.
>
> Uros.
It doesn't work:
x.i:7:1: error: unrecognizable insn:
(call_insn/j 8 7 9 3 (call (mem:QI (reg:DI 62) [0 *foo.0_1 S1 A8])
(const_int 0 [0])) x.i:6 -1
(nil)
(nil))
x.i:7:1: internal compiler error: in extract_insn, at recog.c:2123
Please submit a full bug report,
with preprocessed source if appropriate.
See <http://gcc.gnu.org/bugs.html> for instructions.
make: *** [x.s] Error 1
I will investigate it.
--
H.J.