This is the mail archive of the gcc@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]

Re: Question about strange register calling truncates to SImode on x86_64


Hello Andrew,

> -mcmodel=small'
>   Generate code for the small code model: the program and its
>   symbols must be linked in the lower 2 GB of the address space.
>   Pointers are 64 bits.  Programs can be statically or dynamically
>   linked.  This is the default code model.

You are right, the documentation I read, too. But as described even for 
the small-model pointers are 64-bit and are treated beside the argument 
passing via register  correctly. The problem is that a function just set 
the lower 32-bit of the register, but the method using this register as 
argument uses the 64-bit register variant, which means the upper 32-bit of 
the register have random values..

E.g: The c code
        int foo(const char *h,int n) { n+=(int) *h; return n; }
        int doo(int n) { return foo("abc ",n); }

Leads to the assembly on x86_64 (small)

        .file   "test.c"
        .text
.globl _foo
        .def    _foo;   .scl    2;      .type   32;     .endef
_foo:
LFB2:
        pushq   %rbp
LCFI0:
        movq    %rsp, %rbp
LCFI1:
        movq    %rcx, -8(%rbp)
        movl    %edx, -12(%rbp)
        movq    -8(%rbp), %rax
        movzbl  (%rax), %eax
        movsbl  %al,%eax
        addl    %eax, -12(%rbp)
        movl    -12(%rbp), %eax
        leave
        ret
LFE2:
        .section .rdata,"dr"
LC0:
        .ascii "abc \0"
        .text
.globl _doo
        .def    _doo;   .scl    2;      .type   32;     .endef
_doo:
LFB3:
        pushq   %rbp
LCFI2:
        movq    %rsp, %rbp
LCFI3:
        subq    $8, %rsp
LCFI4:
        movl    %ecx, -4(%rbp)
        movl    -4(%rbp), %edx
        movl    $LC0, %ecx
        call    _foo
        leave
        ret
...

You see, that function "doo" passes the symbolRef LC0 via ecx to function 
foo. But function "foo" uses as input argument rcx for the pointer.

I think the definition of  in i386.md is the reason for this incorrect 
behaviour. I sent a small patch which seems to solve this problem quite 
well without side-effect.


Regards,
 i.A. Kai Tietz

--- gcc-4-2-20060930_org/gcc-4.2-20060930/gcc/config/i386/i386.md 
2006-09-07 19:53:18.000000000 +0200
+++ gcc-4.2-20060930/gcc/config/i386/i386.md    2006-10-11 
09:44:36.610866100 +0200
@@ -2008,9 +2008,7 @@
       return "lea{q}\t{%a1, %0|%0, %a1}";
     default:
       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
-      if (get_attr_mode (insn) == MODE_SI)
-       return "mov{l}\t{%k1, %k0|%k0, %k1}";
-      else if (which_alternative == 2)
+      if (which_alternative == 2)
        return "movabs{q}\t{%1, %0|%0, %1}";
       else
        return "mov{q}\t{%1, %0|%0, %1}";


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