Skip to content

Commit

Permalink
Merge pull request #1969 from WalterBright/fixldiv
Browse files Browse the repository at this point in the history
fix ldiv for shared libraries
  • Loading branch information
yebblies committed May 7, 2013
2 parents 654de78 + 8cb13b3 commit 041f86c
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 10 deletions.
66 changes: 63 additions & 3 deletions src/backend/cod1.c
Expand Up @@ -1958,6 +1958,11 @@ code *callclib(elem *e,unsigned clib,regm_t *pretregs,regm_t keepmask)
};
static symbol clibldiv2 = Y(mAX|mBX|mCX|mDX,"_LDIV2__");
static symbol clibuldiv2 = Y(mAX|mBX|mCX|mDX,"_ULDIV2__");

static symbol clibldiv3 = Y(mAX|mBX|mCX|mDX,"_divdi3");
static symbol clibuldiv3 = Y(mAX|mBX|mCX|mDX,"_udivdi3");
static symbol cliblmod3 = Y(mAX|mBX|mCX|mDX,"_moddi3");
static symbol clibulmod3 = Y(mAX|mBX|mCX|mDX,"_umoddi3");
#else
static symbol lib[CLIBMAX] =
{
Expand Down Expand Up @@ -2157,12 +2162,28 @@ code *callclib(elem *e,unsigned clib,regm_t *pretregs,regm_t keepmask)
#if TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_OPENBSD || TARGET_SOLARIS
clibldiv2.Stype = tsclib;
clibuldiv2.Stype = tsclib;
clibldiv3.Stype = tsclib;
clibuldiv3.Stype = tsclib;
cliblmod3.Stype = tsclib;
clibulmod3.Stype = tsclib;
#if MARS
clibldiv2.Sxtrnnum = 0;
clibldiv2.Stypidx = 0;

clibuldiv2.Sxtrnnum = 0;
clibuldiv2.Stypidx = 0;

clibldiv3.Sxtrnnum = 0;
clibldiv3.Stypidx = 0;

clibuldiv3.Sxtrnnum = 0;
clibuldiv3.Stypidx = 0;

cliblmod3.Sxtrnnum = 0;
cliblmod3.Stypidx = 0;

clibulmod3.Sxtrnnum = 0;
clibulmod3.Stypidx = 0;
#endif
#endif
if (!I16)
Expand Down Expand Up @@ -2261,9 +2282,38 @@ code *callclib(elem *e,unsigned clib,regm_t *pretregs,regm_t keepmask)
code *cgot = NULL;
bool pushebx = false;
#if TARGET_LINUX || TARGET_FREEBSD || TARGET_OPENBSD || TARGET_SOLARIS
if (config.flags3 & CFG3pic && I32)
if (I32)
{
cgot = load_localgot(); // EBX gets set to this value
/* Pass EBX on the stack instead, this is because EBX is used
* for shared library function calls
*/
if (config.flags3 & CFG3pic)
{
cgot = load_localgot(); // EBX gets set to this value
}
#if TARGET_LINUX
switch (clib)
{
case CLIBldiv:
s = &clibldiv3;
pushebx = true;
break;
case CLIBlmod:
s = &cliblmod3;
pushebx = true;
info[clib].retregs32 = mAX|mDX;
break;
case CLIBuldiv:
s = &clibuldiv3;
pushebx = true;
break;
case CLIBulmod:
s = &clibulmod3;
pushebx = true;
info[clib].retregs32 = mAX|mDX;
break;
}
#else
switch (clib)
{ // EBX is a parameter to these, so push it on the stack before load_localgot()
case CLIBldiv:
Expand All @@ -2277,6 +2327,7 @@ code *callclib(elem *e,unsigned clib,regm_t *pretregs,regm_t keepmask)
pushebx = true;
break;
}
#endif
}
#endif
makeitextern(s);
Expand All @@ -2290,8 +2341,17 @@ code *callclib(elem *e,unsigned clib,regm_t *pretregs,regm_t keepmask)
}
}
if (pushebx)
{ c = gen1(c, 0x50 + BX); // PUSH EBX
{
#if TARGET_LINUX
c = gen1(c, 0x50 + CX); // PUSH ECX
c = gen1(c, 0x50 + BX); // PUSH EBX
c = gen1(c, 0x50 + DX); // PUSH EDX
c = gen1(c, 0x50 + AX); // PUSH EAX
nalign += 4 * REGSIZE;
#else
c = gen1(c, 0x50 + BX); // PUSH EBX
nalign += REGSIZE;
#endif
}
c = cat(c, cgot); // EBX = localgot
c = gencs(c,(LARGECODE) ? 0x9A : 0xE8,0,FLfunc,s); // CALL s
Expand Down
14 changes: 7 additions & 7 deletions src/backend/cod4.c
Expand Up @@ -1480,7 +1480,7 @@ code *cdmulass(elem *e,regm_t *pretregs)
cs.Irm |= modregrm(0,DX,0);
gen(cl,&cs); /* MOV DX,EA+2 */
getlvalue_lsw(&cs);
retregs = 0;
retregs = mDX | mAX;
if (config.target_cpu >= TARGET_PentiumPro && op == OPmulass)
{
/* IMUL ECX,EAX
Expand All @@ -1495,21 +1495,21 @@ code *cdmulass(elem *e,regm_t *pretregs)
gen2(c,0x03,modregrm(3,CX,DX));
gen2(c,0xF7,modregrm(3,4,BX));
gen2(c,0x03,modregrm(3,DX,CX));
retregs = mDX | mAX;
}
else
{ if (op == OPmodass)
retregs = mBX | mCX;
c = callclib(e,lib,&retregs,idxregm(&cs));
reg = (op == OPmodass) ? BX : AX;
retregs = mask[reg];
}
reg = findreglsw(retregs);
cs.Iop = 0x89;
NEWREG(cs.Irm,reg);
gen(c,&cs); /* MOV EA,lsreg */
reg = (op == OPmodass) ? CX : DX;
retregs |= mask[reg];
reg = findregmsw(retregs);
NEWREG(cs.Irm,reg);
getlvalue_msw(&cs);
gen(c,&cs); /* MOV EA+2,msreg */
if (e1->Ecount) /* if we gen a CSE */
if (e1->Ecount) // if we gen a CSE
cssave(e1,retregs,EOP(e1));
freenode(e1);
cg = fixresult(e,retregs,pretregs);
Expand Down

0 comments on commit 041f86c

Please sign in to comment.