team
asked on
Assembly compile error
HI,
I am trying to compile a package called TMPI. I am facing a problem with this part of the code. I am compiling this for a machine that has a athlon processor and using gcc as a compiler
tmpi_i386.h
----
#ifndef _I386_H_
#define _I386_H_
#ifdef __SMP__
#define LOCK_PREFIX "lock ; "
#else
#define LOCK_PREFIX ""
#endif
/* some hacks to defeat gcc over-optimizations */
struct __dummy { unsigned long a[100]; };
#define ADDR (*(volatile struct __dummy *)addr)
#endif
----------------
# include "tmpi_i386.h"
__inline__ int cas32(volatile int *addr, int old, int new)
{
char ret;
__asm__ __volatile__(LOCK_PREFIX
"cmpxchg %2, %1\n\t" /* swap values if current value
is known */
"sete %0" /* read success/fail from EF */
: "=q" (ret), "=m" (ADDR)
: "r" (new), "a" (old)
: "%eax" );
return (int)ret;
}
int cas64(volatile long long *ptr, long long old, long long new);
__inline__ int casp(void * *pval, void * old, void * new)
{
/**
* somehow I have to decide the size of (void *)
* during the runtime.
*/
if (sizeof(void *)==sizeof(int))
return cas32((int*)pval, (int)old, (int)new);
else
return cas64((long long *)pval, (long long)old, (long long)new);
}
__inline__ int test_and_set(volatile void *addr, int bit)
{
int oldbit;
__asm__ __volatile__(LOCK_PREFIX
"btsl %2, %1\n\t" /* set bit, store old in CF */
"sbbl %0, %0" /* oldbit -= CF */
: "=r" (oldbit),"=m" (ADDR)
: "Ir" (bit));
return (-oldbit);
}
__inline__ int test_and_clear(volatile void *addr, int bit)
{
int oldbit;
__asm__ __volatile__(LOCK_PREFIX
"btrl %2, %1\n\t" /* clear bit, store old in CF */
"sbbl %0, %0" /* oldbit -= CF */
: "=r" (oldbit), "=m" (ADDR)
: "Ir" (bit));
return (-oldbit);
}
__inline__ int test_and_change(volatile void *addr, int bit)
{
int oldbit;
__asm__ __volatile__(LOCK_PREFIX
"btcl %2, %1\n\t" /* change bit, store in CF */
"sbbl %0, %0" /* oldbit -= CF */
: "=r" (oldbit), "=m" (ADDR)
: "Ir" (bit));
return (-oldbit);
}
__inline__ int anf32(volatile int *ptr, int val)
{
int old;
if (!val) return *ptr;
do {
old=*ptr;
} while (!cas32(ptr, old, old+val));
return old+val;
}
__inline__ int snf32(volatile int *ptr, int val)
{
int old;
if (!val) return *ptr;
do {
old=*ptr;
} while (!cas32(ptr, old, old-val));
return old-val;
}
__inline__ int fna32(volatile int *ptr, int val)
{
int old;
if (!val) return *ptr;
do {
old=*ptr;
} while (!cas32(ptr, old, old+val));
return old;
}
__inline__ int fns32(volatile int *ptr, int val)
{
int old;
if (!val) return *ptr;
do {
old=*ptr;
} while (!cas32(ptr, old, old-val));
return old;
}
__inline__ long long anf64(volatile long long *ptr, long long val)
{
long long old;
if (!val) return *ptr;
do {
old=*ptr;
} while (!cas64(ptr, old, old+val));
return old+val;
}
__inline__ int snf64(volatile long long *ptr, long long val)
{
long long old;
if (!val) return *ptr;
do {
old=*ptr;
} while (!cas64(ptr, old, old-val));
return old-val;
}
-------------------------- -
error :
cc -O -Wall -I. -D__SMP__ -c -o atomic.o atomic.c
atomic.c: In function `casp':
atomic.c:28: warning: cast from pointer to integer of different size
atomic.c:28: warning: cast from pointer to integer of different size
atomic.c: In function `cas32':
atomic.c:13: Invalid `asm' statement:
atomic.c:13: fixed or forbidden register 0 (ax) was spilled for class AREG.
atomic.c: In function `casp':
atomic.c:13: Invalid `asm' statement:
atomic.c:13: fixed or forbidden register 0 (ax) was spilled for class AREG.
atomic.c: In function `anf32':
atomic.c:13: Invalid `asm' statement:
atomic.c:13: fixed or forbidden register 0 (ax) was spilled for class AREG.
atomic.c: In function `snf32':
atomic.c:13: Invalid `asm' statement:
atomic.c:13: fixed or forbidden register 0 (ax) was spilled for class AREG.
atomic.c: In function `fna32':
atomic.c:13: Invalid `asm' statement:
atomic.c:13: fixed or forbidden register 0 (ax) was spilled for class AREG.
atomic.c: In function `fns32':
atomic.c:13: Invalid `asm' statement:
atomic.c:13: fixed or forbidden register 0 (ax) was spilled for class AREG.
make: *** [atomic.o] Error 1
-------------------------- ---------- -------
I am trying to compile a package called TMPI. I am facing a problem with this part of the code. I am compiling this for a machine that has a athlon processor and using gcc as a compiler
tmpi_i386.h
----
#ifndef _I386_H_
#define _I386_H_
#ifdef __SMP__
#define LOCK_PREFIX "lock ; "
#else
#define LOCK_PREFIX ""
#endif
/* some hacks to defeat gcc over-optimizations */
struct __dummy { unsigned long a[100]; };
#define ADDR (*(volatile struct __dummy *)addr)
#endif
----------------
# include "tmpi_i386.h"
__inline__ int cas32(volatile int *addr, int old, int new)
{
char ret;
__asm__ __volatile__(LOCK_PREFIX
"cmpxchg %2, %1\n\t" /* swap values if current value
is known */
"sete %0" /* read success/fail from EF */
: "=q" (ret), "=m" (ADDR)
: "r" (new), "a" (old)
: "%eax" );
return (int)ret;
}
int cas64(volatile long long *ptr, long long old, long long new);
__inline__ int casp(void * *pval, void * old, void * new)
{
/**
* somehow I have to decide the size of (void *)
* during the runtime.
*/
if (sizeof(void *)==sizeof(int))
return cas32((int*)pval, (int)old, (int)new);
else
return cas64((long long *)pval, (long long)old, (long long)new);
}
__inline__ int test_and_set(volatile void *addr, int bit)
{
int oldbit;
__asm__ __volatile__(LOCK_PREFIX
"btsl %2, %1\n\t" /* set bit, store old in CF */
"sbbl %0, %0" /* oldbit -= CF */
: "=r" (oldbit),"=m" (ADDR)
: "Ir" (bit));
return (-oldbit);
}
__inline__ int test_and_clear(volatile void *addr, int bit)
{
int oldbit;
__asm__ __volatile__(LOCK_PREFIX
"btrl %2, %1\n\t" /* clear bit, store old in CF */
"sbbl %0, %0" /* oldbit -= CF */
: "=r" (oldbit), "=m" (ADDR)
: "Ir" (bit));
return (-oldbit);
}
__inline__ int test_and_change(volatile void *addr, int bit)
{
int oldbit;
__asm__ __volatile__(LOCK_PREFIX
"btcl %2, %1\n\t" /* change bit, store in CF */
"sbbl %0, %0" /* oldbit -= CF */
: "=r" (oldbit), "=m" (ADDR)
: "Ir" (bit));
return (-oldbit);
}
__inline__ int anf32(volatile int *ptr, int val)
{
int old;
if (!val) return *ptr;
do {
old=*ptr;
} while (!cas32(ptr, old, old+val));
return old+val;
}
__inline__ int snf32(volatile int *ptr, int val)
{
int old;
if (!val) return *ptr;
do {
old=*ptr;
} while (!cas32(ptr, old, old-val));
return old-val;
}
__inline__ int fna32(volatile int *ptr, int val)
{
int old;
if (!val) return *ptr;
do {
old=*ptr;
} while (!cas32(ptr, old, old+val));
return old;
}
__inline__ int fns32(volatile int *ptr, int val)
{
int old;
if (!val) return *ptr;
do {
old=*ptr;
} while (!cas32(ptr, old, old-val));
return old;
}
__inline__ long long anf64(volatile long long *ptr, long long val)
{
long long old;
if (!val) return *ptr;
do {
old=*ptr;
} while (!cas64(ptr, old, old+val));
return old+val;
}
__inline__ int snf64(volatile long long *ptr, long long val)
{
long long old;
if (!val) return *ptr;
do {
old=*ptr;
} while (!cas64(ptr, old, old-val));
return old-val;
}
--------------------------
error :
cc -O -Wall -I. -D__SMP__ -c -o atomic.o atomic.c
atomic.c: In function `casp':
atomic.c:28: warning: cast from pointer to integer of different size
atomic.c:28: warning: cast from pointer to integer of different size
atomic.c: In function `cas32':
atomic.c:13: Invalid `asm' statement:
atomic.c:13: fixed or forbidden register 0 (ax) was spilled for class AREG.
atomic.c: In function `casp':
atomic.c:13: Invalid `asm' statement:
atomic.c:13: fixed or forbidden register 0 (ax) was spilled for class AREG.
atomic.c: In function `anf32':
atomic.c:13: Invalid `asm' statement:
atomic.c:13: fixed or forbidden register 0 (ax) was spilled for class AREG.
atomic.c: In function `snf32':
atomic.c:13: Invalid `asm' statement:
atomic.c:13: fixed or forbidden register 0 (ax) was spilled for class AREG.
atomic.c: In function `fna32':
atomic.c:13: Invalid `asm' statement:
atomic.c:13: fixed or forbidden register 0 (ax) was spilled for class AREG.
atomic.c: In function `fns32':
atomic.c:13: Invalid `asm' statement:
atomic.c:13: fixed or forbidden register 0 (ax) was spilled for class AREG.
make: *** [atomic.o] Error 1
--------------------------
The code is meant for i386 machines ... since you are trying to compile it on athlon it will not work ... you can either use a cross compiler to compile it (I am not sure if you have a cross assembler to generate athlon exe from i386 assembly but will search) or you can rewrite it to equivalent athlon assembly code
ok, try this
http://freshmeat.net/projects/tdasm/
http://freshmeat.net/projects/tdasm/
ASKER
err i thought athlon instruction set was based on x86 and gcc shouldn't be really complaining.
ASKER
i will check out tdasm
I am not an assembly expert but I really do not think both of them have same assembly.
Wait for someone more experienced with assembly to comment on this .... It might also help to post a pointer to this question in the assembly section
https://www.experts-exchange.com/Programming/Programming_Languages/Assembly/
Wait for someone more experienced with assembly to comment on this .... It might also help to post a pointer to this question in the assembly section
https://www.experts-exchange.com/Programming/Programming_Languages/Assembly/
ASKER
error compiling tdasm: wonder if i should start a seperate thread on this.
************************** ********** ********** ********** ********** *********/
#include <stdio.h>
#include <string>
#include <vector>
#include "tablecomp.h"
struct {
int lx;
const char *ls;
} lex2str[] = { <------------------------- ------
#ifndef BISON_Y_TAB_H
# define BISON_Y_TAB_H
#ifndef YYSTYPE
# define YYSTYPE yystype
# define YYSTYPE_IS_TRIVIAL 1
#endif
# define ENDIAN 257
# define ENUM 258
# define INSTFORMAT 259
# define OPERAND 260
-----------------------
sed -f printyylex.sed <tablecomp.h >printyylex.cc
c++ -DHAVE_CONFIG_H -I. -I. -I.. -Wall -pedantic -ansi -g3 -O0 -c printyylex.cc
printyylex.cc:102: parse error at end of input
printyylex.cc:24: storage size of `lex2str' isn't known
make[2]: *** [printyylex.o] Error 1
**************************
#include <stdio.h>
#include <string>
#include <vector>
#include "tablecomp.h"
struct {
int lx;
const char *ls;
} lex2str[] = { <-------------------------
#ifndef BISON_Y_TAB_H
# define BISON_Y_TAB_H
#ifndef YYSTYPE
# define YYSTYPE yystype
# define YYSTYPE_IS_TRIVIAL 1
#endif
# define ENDIAN 257
# define ENUM 258
# define INSTFORMAT 259
# define OPERAND 260
-----------------------
sed -f printyylex.sed <tablecomp.h >printyylex.cc
c++ -DHAVE_CONFIG_H -I. -I. -I.. -Wall -pedantic -ansi -g3 -O0 -c printyylex.cc
printyylex.cc:102: parse error at end of input
printyylex.cc:24: storage size of `lex2str' isn't known
make[2]: *** [printyylex.o] Error 1
you ran configure before make ?
looks like tdasm has not been updated for quite sometime ... May be we should be looking for something more recent
Athlon is 99.9999% code compatible with x86, so that's not the problem.
The problem is the code is trying to use some very fancy __asm tricks.
The "register spilled" problem is because the compiler thinks the __asm code is trying to use ax in a conflicting way-- as an operand and as a result. You might be able to get around it by turning down the optimization level or using some other gcc option that tells gcc to not think so hard over this sequence.
One roundabout way:
I would suggest for starters you think bout using some system API to do these test-and-set operations. Most os-s have API's for this. They're a tad slower than an inline lock-and-special-CPU-instr uction, but a lot less finicky.
The problem is the code is trying to use some very fancy __asm tricks.
The "register spilled" problem is because the compiler thinks the __asm code is trying to use ax in a conflicting way-- as an operand and as a result. You might be able to get around it by turning down the optimization level or using some other gcc option that tells gcc to not think so hard over this sequence.
One roundabout way:
I would suggest for starters you think bout using some system API to do these test-and-set operations. Most os-s have API's for this. They're a tad slower than an inline lock-and-special-CPU-instr
ASKER
well it turned out to be a gcc bug in prior versions of gcc-3.0 . I had used 2.95 earlier and now used 3.2.2 and the errors got reduced to
cc -O -Wall -I. -D__SMP__ -c -o atomic.o atomic.c
atomic.c: In function `casp':
atomic.c:28: warning: cast from pointer to integer of different size
atomic.c:28: warning: cast from pointer to integer of different size
atomic.c: In function `cas32':
atomic.c:7: can't find a register in class `AREG' while reloading `asm'
make[2]: *** [atomic.o] Error 1
make[1]: *** [machine] Error 2
make: *** [src] Error 2
cc -O -Wall -I. -D__SMP__ -c -o atomic.o atomic.c
atomic.c: In function `casp':
atomic.c:28: warning: cast from pointer to integer of different size
atomic.c:28: warning: cast from pointer to integer of different size
atomic.c: In function `cas32':
atomic.c:7: can't find a register in class `AREG' while reloading `asm'
make[2]: *** [atomic.o] Error 1
make[1]: *** [machine] Error 2
make: *** [src] Error 2
ASKER
sunnycoder: yes i did run configure
I recommend PAQ and refund: grg99's suggestion is a good one (even if it is not the specific solution to this particular problem) and the team's finding of bugs in old versions of gcc is worth retaining in the database.
-- Dan
-- Dan
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.