[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: libqalculate FTBFS on mips* (ball, rem)



Thiemo Seufer wrote:
[snip]
> > I've attached a small testcase package.  Go to the modules.h file where
> > the CL_JUMP_TO macro is defined in the __mips__ case.  I define two
> > static objects, one prints an 'A' at construction, one a 'B', main()
> > prints a newline.  The effect of the code is that the output should always
> > be "AB\n", never "BA\n":
> > 
> > $ g++ -O -c moda.cc
> > $ g++ -O -c modb.cc
> > $ g++ -O main.cc moda.o modb.o && ./a.out
> > AB
> > $ g++ -O main.cc modb.o moda.o && ./a.out
> > AB
> > 
> > Regardless of which one of the three definitions of CL_JUMP_TO I use, the
> > program works with woody.  With sarge, only the __asm__ __volatile__("br "
> > #addr) version works, all others segfault (or cause an illegal insn).
> 
> I'll have a look, thanks.

The "jr" failed because the mips assembler fails to take the segment
offset of .text into account, which leads to the relevant relocation
being NULL. The appended diff aginst the modules.h of your testcase
- removes the additional checks for __mips{el,64}__ because __mips__ is
  generally defined for those configurations.
- globalizes the jump label for __mips__ as a workaround.
- Uses a more reliable CL_JUMP_TO version which doesn't depend on 
  undocumented compiler behaviour to handle the promotion from a
  memory address to a register suitable for the "r" constraint.

The last change may be advisable for all architectures which use a "r"
constraint.


Thiemo


--- modules.h	2005-09-05 21:01:36.000000000 +0200
+++ modules.h.new	2005-09-05 22:57:19.000000000 +0200
@@ -64,7 +64,7 @@
   #endif
   // Globalize a label defined in the same translation unit.
   // See macro ASM_GLOBALIZE_LABEL in the gcc sources.
-  #if defined(__i386__) || defined(__m68k__) || defined(__mips__) || defined(__mipsel__) || defined(__mips64__) || defined(__alpha__) || defined(__rs6000__) || defined(__powerpc64__) || defined(__x86_64__) || defined(__s390__)
+  #if defined(__i386__) || defined(__m68k__) || defined(__mips__) || defined(__alpha__) || defined(__rs6000__) || defined(__powerpc64__) || defined(__x86_64__) || defined(__s390__)
     // Some m68k systems use "xdef" or "global" or ".global"...
     #define CL_GLOBALIZE_LABEL(label)  __asm__("\t.globl " label);
   #endif
@@ -84,7 +84,7 @@
   #ifndef CL_GLOBALIZE_LABEL
     #define CL_GLOBALIZE_LABEL(label)
   #endif
-  #if defined(__rs6000__) || defined(_WIN32)
+  #if defined(__rs6000__) || defined(_WIN32) || (__mips__)
     #define CL_GLOBALIZE_JUMP_LABEL(label)  CL_GLOBALIZE_LABEL(ASM_UNDERSCORE_PREFIX #label)
   #else
     #define CL_GLOBALIZE_JUMP_LABEL(label)
@@ -139,10 +139,12 @@
   #if defined(__m68k__)
     #define CL_JUMP_TO(addr)  ASM_VOLATILE("jmp %0@" : : "a" ((void*)(addr)))
   #endif
-  #if defined(__mips__) || defined(__mipsel__)
-    #define CL_JUMP_TO(addr)  ASM_VOLATILE("b " ASM_UNDERSCORE_PREFIX #addr)
-//    #define CL_JUMP_TO(addr)  ASM_VOLATILE("jr %0" : : "r" ((void*)(addr)))
-//    #define CL_JUMP_TO(addr)  ASM_VOLATILE("%*j %0" : : "d" ((void*)(addr)))
+  #if defined(__mips__)
+    #define CL_JUMP_TO(addr)			\
+    ({						\
+        register void *_a = (void *)(addr);	\
+        ASM_VOLATILE("jr %0" : : "r" (_a));	\
+    })
   #endif
   #if defined(__sparc__) || defined(__sparc64__)
     #define CL_JUMP_TO(addr)  ASM_VOLATILE("jmp %0\n\tnop" : : "r" ((void*)(addr)))



Reply to: