The following source code causes a wrong assembly output :

 1 "main.cpp"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "main.cpp"
# 1 "far_pointers.h" 1
# 13 "far_pointers.h"
# 1 "c:\\mingw\\bin\\../lib/gcc/mingw32/4.5.0/include/stddef.h" 1 3 4
# 149 "c:\\mingw\\bin\\../lib/gcc/mingw32/4.5.0/include/stddef.h" 3 4
typedef int ptrdiff_t;
# 211 "c:\\mingw\\bin\\../lib/gcc/mingw32/4.5.0/include/stddef.h" 3 4
typedef unsigned int size_t;
# 14 "far_pointers.h" 2

template <class T> class far_pointer
{
protected:
 unsigned short segmentSelector;
 T* offset;

public:

 inline far_pointer(unsigned short argSegmentSelector, T* argOffset)
:segmentSelector(argSegmentSelector), offset(argOffset)
 {}

 template <class Tp> inline operator far_pointer<Tp>()
 {
  return far_pointer<Tp>(segmentSelector, (Tp*) offset);
 }

 inline T* getOffset()
 {
  return offset;
 }

 inline unsigned short getSegmentselector()
 {
  return segmentSelector;
 }







 inline T operator*(void)
 {
  T item;
  __asm__
  (
   "                    .intel_syntax noprefix;     \n                  mov gs,
%1;                 \n                  mov %0, gs:[%2];            \n         
        "




   :"=q"(item)
   :"r"(this->segmentSelector), "g"(this->offset)
  );
  return item;
 }






 inline far_pointer<T>& operator++(void)
 {
  offset++;
  return *this;
 }

 inline far_pointer<T>& operator--(void)
 {
  offset--;
  return *this;
 }

 inline size_t operator-(far_pointer<T> const& subs)
 {
  return offset-subs.offset;
 }

 inline far_pointer operator+(int argDecal)
 {
  return far_pointer(segmentSelector, offset + argDecal);
 }

 inline far_pointer operator-(int argDecal)
 {
  return far_pointer(segmentSelector, offset - argDecal);
 }

 inline far_pointer operator+(unsigned argDecal)
 {
  return far_pointer(segmentSelector, offset + argDecal);
 }

 inline far_pointer operator-(unsigned argDecal)
 {
  return far_pointer(segmentSelector, offset - argDecal);
 }

 inline void operator+=(unsigned argDecal)
 {
  offset += argDecal;
 }

 inline void operator-=(unsigned argDecal)
 {
  offset -= argDecal;
 }
 inline void operator+=(int argDecal)
 {
  offset += argDecal;
 }

 inline void operator-=(int argDecal)
 {
  offset -= argDecal;
 }

 inline far_pointer operator+(long argDecal)
 {
  return far_pointer(segmentSelector, offset + argDecal);
 }

 inline far_pointer operator-(long argDecal)
 {
  return far_pointer(segmentSelector, offset - argDecal);
 }

 inline far_pointer operator+(unsigned long argDecal)
 {
  return far_pointer(segmentSelector, offset + argDecal);
 }

 inline far_pointer operator-(unsigned long argDecal)
 {
  return far_pointer(segmentSelector, offset - argDecal);
 }

 inline void operator+=(unsigned long argDecal)
 {
  offset += argDecal;
 }

 inline void operator-=(unsigned long argDecal)
 {
  offset -= argDecal;
 }
 inline void operator+=(long argDecal)
 {
  offset += argDecal;
 }

 inline void operator-=(long argDecal)
 {
  offset -= argDecal;
 }

 inline bool operator<(far_pointer<T> const& ptr)
 {
 return offset < ptr.offset;
 }

 inline bool operator>(far_pointer<T> const& ptr)
 {
 return offset > ptr.offset;
 }

 inline bool operator<=(far_pointer<T> const& ptr)
 {
 return offset <= ptr.offset;
 }

 inline bool operator>=(far_pointer<T> const& ptr)
 {
 return offset >= ptr.offset;
 }

 inline bool operator!=(far_pointer<T> const& ptr)
 {
 return offset != ptr.offset || segmentSelector != ptr.segmentSelector;
 }

 inline bool operator==(far_pointer<T> const& ptr)
 {
 return offset == ptr.offset && segmentSelector == ptr.segmentSelector;
 }
static const far_pointer<T> NULL_FAR_POINTER;
};

template <class T> const far_pointer<T> far_pointer<T>::NULL_FAR_POINTER(0,(T*)
0);
# 2 "main.cpp" 2

char u;

void toto(far_pointer<unsigned char> pt)
{
    u = *pt;
}

int main(int argc, char **argv)
{
 unsigned short dataSeg = 0;
 asm (
      "                                                         .intel_syntax
noprefix;     \n                          mov %0, cs;                 \n       
                  "



   : "=r"(dataSeg)
 );
 far_pointer<unsigned char> pt(dataSeg, (unsigned char*) &main);
 toto(pt);
}

--------------------------------------------------------------------------------

COLLECT_GCC_OPTIONS='-c' '-masm=intel' '-save-temps' '-v' '-O1' '-o'
'./Release/main.o' '-I.' '-shared-libgcc' '-mtune=i386' '-march=i386'
 c:/mingw/bin/../libexec/gcc/mingw32/4.5.0/cc1plus.exe -fpreprocessed main.ii
-quiet -dumpbase main.cpp -masm=intel -mtune=i386 -march=i386 -auxbase-strip
./Release/main.o -O1 -version -o main.s
GNU C++ (GCC) version 4.5.0 (mingw32)
        compiled by GNU C version 4.5.0, GMP version 5.0.1, MPFR version 2.4.1,
MPC version 0.8.1
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
GNU C++ (GCC) version 4.5.0 (mingw32)
        compiled by GNU C version 4.5.0, GMP version 5.0.1, MPFR version 2.4.1,
MPC version 0.8.1
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
Compiler executable checksum: 639ec8dd7c9bc03705b4424f5e166212
COLLECT_GCC_OPTIONS='-c' '-masm=intel' '-save-temps' '-v' '-O1' '-o'
'./Release/main.o' '-I.' '-shared-libgcc' '-mtune=i386' '-march=i386'
 c:/mingw/bin/../lib/gcc/mingw32/4.5.0/../../../../mingw32/bin/as.exe -o
./Release/main.o main.s
main.s: Messages de l'assembleur:
main.s:22: ERREUR: `al' not allowed with `movl'
mingw32-make.exe[1]: *** [Release/main.o] Error 1
"mingw32-make.exe": *** [All] Error 2


The origin is the inlining of T operator*(void) in toto(far_pointer<unsigned
char> pt) in main.ii.



This output is the same whatever optimization level but with -g. In this last
case, there is no error.

A similar ouput is observable on Linux with g++-4.5 (Ubuntu 4.5.0-3ubuntu1)
4.5.1 20100519 (prerelease) with the same command-line.
The error message differs, nevertheless:

main.s: Assembler messages:
main.s:31: Error: operand type mismatch for `movsbl'
main.s:32: Error: no such instruction: `movl %eax,8(%esp)'
main.s:33: Error: no such instruction: `movl $.LC0,4(%esp)'
main.s:34: Error: no such instruction: `movl $1,(%esp)'
main.s:36: Error: no such instruction: `movl $0,%eax'


-- 
           Summary: [Extended inline asm] wrong assembly generation on IA32
           Product: gcc
           Version: 4.5.0
            Status: UNCONFIRMED
          Severity: major
          Priority: P3
         Component: rtl-optimization
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: dg dot recrutement31 at gmail dot com
  GCC host triplet: Windows Vista 32 bit and Linux 32 bit
GCC target triplet: i386


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=44288

Reply via email to