This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] PR target/9908: Incorrect Intel assembler syntax


The following patch resolves PR target/9908 which is a wrong-code
regression on mainline and the 3.4 branch.  The problem is that
we're currently generating the wrong assembler syntax with -masm=intel
for indirect jumps/calls in the x86 backend.  The test case attached
to the PR no longer triggers the bug on mainline, but can be used to
trigger the failure with 3.4.x.


The bug was accidentally introduced by Jan's patch "x86_64 merger
part 34 - function calling bits part 1", back in April 2001.
http://gcc.gnu.org/ml/gcc-patches/2001-04/msg00298.html

This patch was intended to split patterns into 32-bit and 64-bit
variants, unfortunately the original call_value_1 pattern:

(define_insn "*call_value_1"
  [(set (match_operand 0 "" "")
    (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
          (match_operand:SI 2 "" "")))]
  ""
  "*
{
  if (constant_call_address_operand (operands[1], QImode))
    {
      if (SIBLING_CALL_P (insn))
        return \"jmp\\t%P1\";
      else
        return \"call\\t%P1\";
    }
  if (SIBLING_CALL_P (insn))
    return \"jmp\\t%A1\";
  else
    return \"call\\t%A1\";
}"
  [(set_attr "type" "callv")])


was incorrectly fisioned into two variants:


(define_insn "*call_value_1"
  [(set (match_operand 0 "" "")
    (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
          (match_operand:SI 2 "" "")))]
  "!TARGET_64BIT"
  "*
{
  if (constant_call_address_operand (operands[1], QImode))
    {
      if (SIBLING_CALL_P (insn))
        return \"jmp\\t%P1\";
      else
        return \"call\\t%P1\";
    }
  if (SIBLING_CALL_P (insn))
    return \"jmp\\t%*%1\";
  else
    return \"call\\t%*%1\";
}"
  [(set_attr "type" "callv")])

(define_insn "*call_value_1_rex64"
  [(set (match_operand 0 "" "")
    (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
          (match_operand:DI 2 "" "")))]
  "TARGET_64BIT"
  "*
{
  if (constant_call_address_operand (operands[1], QImode))
    {
      if (SIBLING_CALL_P (insn))
        return \"jmp\\t%P1\";
      else
        return \"call\\t%P1\";
    }
  if (SIBLING_CALL_P (insn))
    return \"jmp\\t%A1\";
  else
    return \"call\\t%A1\";
}"
  [(set_attr "type" "callv")])


Notice how the first !TARGET_64BIT variant accidently changes from
%A1 into %*%1 but the 64-bit version is OK.  Probably a cut-n-paste
error, as this change isn't described in the ChangeLog nor the post
to gcc-patches.  Over the next three and a half years the code mutated
and split again (to factor the SIBLING_CALL_P stuff into its own pattern),
but this typo/error was faithfully duplicated and now affects two
patterns.

The following is a simple fix to address the problem.  This patch
has been tested on i686-pc-linux-gnu against both mainline and the
gcc-3_4-branch, with a full "make bootstrap", all default languages,
and regression tested with a top-level "make -k check".  I checked
the gcc 3.4 version manually to confirm it now assembles/executes
the example in bugzilla.


Ok for mainline and the gcc-3_4-branch?



2004-12-01  Roger Sayle  <roger@eyesopen.com>

	PR target/9908
	* config/i386/i386.md (*call_value_1, *sibcall_value_1): Correct
	Intel assembler syntax by using %A1 instead of %*%1.


Index: config/i386/i386.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/i386/i386.md,v
retrieving revision 1.565
diff -c -3 -p -r1.565 i386.md
*** config/i386/i386.md	23 Nov 2004 01:22:58 -0000	1.565
--- config/i386/i386.md	1 Dec 2004 04:24:48 -0000
***************
*** 19878,19884 ****
  {
    if (constant_call_address_operand (operands[1], Pmode))
      return "call\t%P1";
!   return "call\t%*%1";
  }
    [(set_attr "type" "callv")])

--- 19878,19884 ----
  {
    if (constant_call_address_operand (operands[1], Pmode))
      return "call\t%P1";
!   return "call\t%A1";
  }
    [(set_attr "type" "callv")])

***************
*** 19890,19896 ****
  {
    if (constant_call_address_operand (operands[1], Pmode))
      return "jmp\t%P1";
!   return "jmp\t%*%1";
  }
    [(set_attr "type" "callv")])

--- 19890,19896 ----
  {
    if (constant_call_address_operand (operands[1], Pmode))
      return "jmp\t%P1";
!   return "jmp\t%A1";
  }
    [(set_attr "type" "callv")])


Roger
--
Roger Sayle,                         E-mail: roger@eyesopen.com
OpenEye Scientific Software,         WWW: http://www.eyesopen.com/
Suite 1107, 3600 Cerrillos Road,     Tel: (+1) 505-473-7385
Santa Fe, New Mexico, 87507.         Fax: (+1) 505-473-0833


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]