version 1.94, 2004/03/15 07:30:44 |
version 1.95, 2004/03/15 08:44:52 |
|
|
/* $OpenXM: OpenXM_contrib2/asir2000/engine/nd.c,v 1.93 2004/03/13 07:48:30 noro Exp $ */ |
/* $OpenXM: OpenXM_contrib2/asir2000/engine/nd.c,v 1.94 2004/03/15 07:30:44 noro Exp $ */ |
|
|
#include "nd.h" |
#include "nd.h" |
|
|
Line 849 ND nd_add(int mod,ND p1,ND p2) |
|
Line 849 ND nd_add(int mod,ND p1,ND p2) |
|
can += 2; FREENM(s); |
can += 2; FREENM(s); |
} |
} |
s = m2; m2 = NEXT(m2); FREENM(s); |
s = m2; m2 = NEXT(m2); FREENM(s); |
|
break; |
|
case 1: |
|
s = m1; m1 = NEXT(m1); NEXTNM2(mr0,mr,s); |
|
break; |
|
case -1: |
|
s = m2; m2 = NEXT(m2); NEXTNM2(mr0,mr,s); |
|
break; |
|
} |
|
} |
|
if ( !mr0 ) |
|
if ( m1 ) mr0 = m1; |
|
else if ( m2 ) mr0 = m2; |
|
else return 0; |
|
else if ( m1 ) NEXT(mr) = m1; |
|
else if ( m2 ) NEXT(mr) = m2; |
|
else NEXT(mr) = 0; |
|
BDY(p1) = mr0; |
|
SG(p1) = MAX(SG(p1),SG(p2)); |
|
LEN(p1) = LEN(p1)+LEN(p2)-can; |
|
FREEND(p2); |
|
return p1; |
|
} |
|
} |
|
|
|
/* XXX on opteron, the inlined manipulation of destructive additon of |
|
* two NM seems to make gcc optimizer get confused, so the part is |
|
* done in a function. |
|
*/ |
|
|
|
int nm_destructive_add_q(NM *m1,NM *m2,NM *mr0,NM *mr) |
|
{ |
|
NM s; |
|
Q t; |
|
int can; |
|
|
|
addq(CQ(*m1),CQ(*m2),&t); |
|
s = *m1; *m1 = NEXT(*m1); |
|
if ( t ) { |
|
can = 1; NEXTNM2(*mr0,*mr,s); CQ(*mr) = (t); |
|
} else { |
|
can = 2; FREENM(s); |
|
} |
|
s = *m2; *m2 = NEXT(*m2); FREENM(s); |
|
return can; |
|
} |
|
|
|
ND nd_add_q(ND p1,ND p2) |
|
{ |
|
int n,c,can; |
|
ND r; |
|
NM m1,m2,mr0,mr,s; |
|
Q t; |
|
|
|
if ( !p1 ) return p2; |
|
else if ( !p2 ) return p1; |
|
else { |
|
can = 0; |
|
for ( n = NV(p1), m1 = BDY(p1), m2 = BDY(p2), mr0 = 0; m1 && m2; ) { |
|
c = DL_COMPARE(DL(m1),DL(m2)); |
|
switch ( c ) { |
|
case 0: |
|
#if defined(__x86_64__) |
|
can += nm_destructive_add_q(&m1,&m2,&mr0,&mr); |
|
#else |
|
addq(CQ(m1),CQ(m2),&t); |
|
s = m1; m1 = NEXT(m1); |
|
if ( t ) { |
|
can++; NEXTNM2(mr0,mr,s); CQ(mr) = (t); |
|
} else { |
|
can += 2; FREENM(s); |
|
} |
|
s = m2; m2 = NEXT(m2); FREENM(s); |
|
#endif |
break; |
break; |
case 1: |
case 1: |
s = m1; m1 = NEXT(m1); NEXTNM2(mr0,mr,s); |
s = m1; m1 = NEXT(m1); NEXTNM2(mr0,mr,s); |