jjc@UUNET.UU.NET (James Clark) (05/22/89)
I brought up g++ 1.35.0 on a 386 machine running SVR3.2 (386/ix
version 2.0.1) using COFF encapsulation (I used config.g++ i386g). I
had to make one small change to newld.c
*** newld.c.distrib Sun May 21 17:02:18 1989
--- newld.c Sun May 21 17:12:02 1989
***************
*** 255,261 ****
#define INITIALIZE_HEADER outheader.a_machtype = HP9000S200_ID
#endif
#if defined(i386) && !defined(sequent)
! #define INITIALIZE_HEADER outheader.a_machtype = M_386
#endif
#ifdef is68k
--- 255,261 ----
#define INITIALIZE_HEADER outheader.a_machtype = HP9000S200_ID
#endif
#if defined(i386) && !defined(sequent)
! #define INITIALIZE_HEADER N_SET_MACHTYPE (outheader, M_386)
#endif
#ifdef is68k
(This is how the current version of ld.c in binutils defines it).
There seems to be a register allocation problem. I compiled this using just -g.
class symbol {
static const char **table;
static int table_used;
static int table_size;
static char *block;
static int block_size;
const char *s;
public:
symbol(const char *p, int how = 0);
symbol();
unsigned hash();
operator ==(symbol);
operator !=(symbol);
};
inline symbol::symbol() : s(0)
{
}
inline symbol::operator==(symbol p)
{
return s == p.s;
}
inline symbol::operator!=(symbol p)
{
return s != p.s;
}
inline unsigned symbol::hash()
{
return unsigned(s);
}
struct association {
symbol s;
void *v;
association() : v(0) {}
};
class dictionary {
int size;
int used;
double threshold;
double factor;
association *table;
void rehash(int);
public:
dictionary(int);
void *lookup(symbol s, void *v=0); // returns value associated with key
};
static int is_good_size(int p);
void *dictionary::lookup(symbol s, void *v = 0)
{
for (int i = s.hash() % size;
table[i].v != 0;
i == 0 ? i = size - 1: --i)
if (s == table[i].s) {
if (v != 0) {
void *temp = table[i].v;
table[i].v = v;
return temp;
}
else
return table[i].v;
}
++used;
table[i].v = v;
table[i].s = s;
if ((double)used/(double)size >= threshold || used + 1 >= size) {
int old_size = size;
size = int(size*factor);
while (!is_good_size(size))
++size;
association *old_table = table;
table = new association[size];
used = 0;
for (i = 0; i < old_size; i++)
if (old_table[i].v != 0)
(void)lookup(old_table[i].s, old_table[i].v);
}
return 0;
}
It generates incorrect assembler code for line 74:
size = int(size*factor);
Here's the assembler code that's incorrect:
.stabd 68,0,73
movl 8(%ebp),%eax
movl (%eax),%edx
movl %edx,-16(%ebp)
.stabd 68,0,74
fildl (%eax)
fstpl -88(%ebp)
fldl -88(%ebp)
fmull 16(%eax)
fstpl -88(%ebp)
pushl -84(%ebp)
pushl -88(%ebp)
call ___fixdfsi
leal 8(%esp),%esp
movl 8(%ebp),%eax <--- eax isn't available here: it holds the return value
movl %eax,(%eax)
.stabd 68,0,75
If you need the rest of the assembler code, I can easily send it.
James Clark
jjc@jclark.uucp