Message ID | CAMe9rOqQjWEd56mYNc5C6MZpxs1wRXfYwaieiEcXK0nBsY0U9A@mail.gmail.com |
---|---|
State | New |
Headers | show |
On Mon, Mar 5, 2012 at 4:53 AM, H.J. Lu <hjl.tools@gmail.com> wrote: > and compiler does generate the same output. i386.c also has > > xasm = "jmp\t%A0"; > xasm = "call\t%A0"; > > for calls. There are no separate indirect call patterns. For x32, > only indirect register calls have to be in DImode. The direct call > should be in Pmode (SImode). Direct call just expects label to some abolute address that is assumed to fit in 32 bits (see constant_call_address_operand_p). call and jmp insn expect word_mode operands, so please change ix86_expand_call and call patterns in the same way as jump instructions above. > Since x86-64 hardware always zero-extends upper 32bits of 64bit > registers when loading its lower 32bits, it is safe and easier to just > to output 64bit registers for %A than zero-extend it by hand for all > jump/call patterns. No, the instruction expects word_mode operands, so we have to extend values to expected mode. I don't think that patching at insn output time is acceptable. BTW: I propose to split the patch into smaller pieces, dealing with various independent parts separately. Handling jump/call insn is definitely one of them, the other is stringops handling, another prologue/epilogue expansion. Uros.
On Sun, Mar 4, 2012 at 11:47 PM, Uros Bizjak <ubizjak@gmail.com> wrote: > On Mon, Mar 5, 2012 at 4:53 AM, H.J. Lu <hjl.tools@gmail.com> wrote: > >> and compiler does generate the same output. i386.c also has >> >> xasm = "jmp\t%A0"; >> xasm = "call\t%A0"; >> >> for calls. There are no separate indirect call patterns. For x32, >> only indirect register calls have to be in DImode. The direct call >> should be in Pmode (SImode). > > Direct call just expects label to some abolute address that is assumed > to fit in 32 bits (see constant_call_address_operand_p). > > call and jmp insn expect word_mode operands, so please change > ix86_expand_call and call patterns in the same way as jump > instructions above. > >> Since x86-64 hardware always zero-extends upper 32bits of 64bit >> registers when loading its lower 32bits, it is safe and easier to just >> to output 64bit registers for %A than zero-extend it by hand for all >> jump/call patterns. > > No, the instruction expects word_mode operands, so we have to extend > values to expected mode. I don't think that patching at insn output > time is acceptable. You are right. I found a testcase to show problem: struct foo { void (*f) (void); int i; }; void __attribute__ ((noinline)) bar (struct foo x) { x.f (); } "x" is passed in RDI and the uppper 32bits of RDI is "int i". > BTW: I propose to split the patch into smaller pieces, dealing with > various independent parts separately. Handling jump/call insn is > definitely one of them, the other is stringops handling, another > prologue/epilogue expansion. > I will do that. Thanks.
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 715e7ea..de5cf67 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -11100,10 +11100,15 @@ (set_attr "modrm" "0")]) (define_expand "indirect_jump" - [(set (pc) (match_operand 0 "indirect_branch_operand" ""))]) + [(set (pc) (match_operand 0 "indirect_branch_operand" ""))] + "" +{ + if (TARGET_X32) + operands[0] = convert_memory_address (word_mode, operands[0]); +}) (define_insn "*indirect_jump" - [(set (pc) (match_operand:P 0 "indirect_branch_operand" "rw"))] + [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rw"))] "" "jmp\t%A0" [(set_attr "type" "ibr") @@ -11145,12 +11150,12 @@ operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0, OPTAB_DIRECT); } - else if (TARGET_X32) - operands[0] = convert_memory_address (Pmode, operands[0]); + if (TARGET_X32) + operands[0] = convert_memory_address (word_mode, operands[0]); }) (define_insn "*tablejump_1" - [(set (pc) (match_operand:P 0 "indirect_branch_operand" "rw")) + [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rw")) (use (label_ref (match_operand 1 "" "")))] "" "jmp\t%A0"