From a92f6bf42e547c6978e4e317b4feb2c6610cf518 Mon Sep 17 00:00:00 2001 From: Walter Bright Date: Tue, 23 Aug 2011 14:56:25 -0700 Subject: [PATCH] Issue 6505 - Wrong code for expression involving 8 floats, only with -O --- src/backend/cgen.c | 20 ++++++++++++++++++++ src/backend/cgsched.c | 9 ++++++++- src/backend/cod1.c | 2 ++ src/backend/code.h | 2 ++ 4 files changed, 32 insertions(+), 1 deletion(-) diff --git a/src/backend/cgen.c b/src/backend/cgen.c index a261f2185005..1990cce0bf63 100644 --- a/src/backend/cgen.c +++ b/src/backend/cgen.c @@ -512,6 +512,26 @@ code *genadjesp(code *c, int offset) return c; } +/******************************** + * Generate 'instruction' which tells the scheduler that the fpu stack has + * changed. + */ + +code *genadjfpu(code *c, int offset) +{ code cs; + + if (!I16 && offset) + { + cs.Iop = ESCAPE | ESCadjfpu; + cs.Iflags = 0; + cs.Irex = 0; + cs.IEV2.Vint = offset; + return gen(c,&cs); + } + else + return c; +} + /******************************** * Generate 'nop' */ diff --git a/src/backend/cgsched.c b/src/backend/cgsched.c index 939c402e8fd7..5db85d1e100c 100644 --- a/src/backend/cgsched.c +++ b/src/backend/cgsched.c @@ -1348,6 +1348,11 @@ STATIC void getinfo(Cinfo *ci,code *c) c->Iflags |= CFpsw; break; + case ESCAPE: + if (c->Iop == (ESCAPE | ESCadjfpu)) + ci->fpuadjust = c->IEV2.Vint; + break; + case 0xD0: case 0xD1: case 0xD2: @@ -2691,7 +2696,9 @@ code *schedule(code *c,regm_t scratch) sch.initialize(0); // initialize scheduling table while (c) { - if ((c->Iop == NOP || (c->Iop & 0xFF) == ESCAPE || c->Iflags & CFclassinit) && + if ((c->Iop == NOP || + ((c->Iop & 0xFF) == ESCAPE && c->Iop != (ESCAPE | ESCadjfpu)) || + c->Iflags & CFclassinit) && !(c->Iflags & (CFtarg | CFtarg2))) { code *cn; diff --git a/src/backend/cod1.c b/src/backend/cod1.c index d55fb10bd2f2..1c7a4d3bd070 100644 --- a/src/backend/cod1.c +++ b/src/backend/cod1.c @@ -3081,6 +3081,7 @@ STATIC code * funccall(elem *e,unsigned numpara,unsigned numalign,regm_t *pretre if (retregs & mST0) { + c = genadjfpu(c, 1); if (*pretregs) // if we want the result { //assert(stackused == 0); push87(); // one item on 8087 stack @@ -3092,6 +3093,7 @@ STATIC code * funccall(elem *e,unsigned numpara,unsigned numalign,regm_t *pretre } else if (retregs & mST01) { + c = genadjfpu(c, 2); if (*pretregs) // if we want the result { assert(stackused == 0); push87(); diff --git a/src/backend/code.h b/src/backend/code.h index cdbc99d20f18..3682ddd4470b 100644 --- a/src/backend/code.h +++ b/src/backend/code.h @@ -244,6 +244,7 @@ extern regm_t BYTEREGS; #define ESCframeptr (10 << 8) // replace with load of frame pointer #define ESCdctor (11 << 8) // D object is constructed #define ESCddtor (12 << 8) // D object is destructed + #define ESCadjfpu (13 << 8) // adjust fpustackused by IEV2.Vint #define ASM 0x36 // string of asm bytes, actually an SS: opcode @@ -876,6 +877,7 @@ code *genlinnum(code *,Srcpos); void cgen_linnum(code **pc,Srcpos srcpos); void cgen_prelinnum(code **pc,Srcpos srcpos); code *genadjesp(code *c, int offset); +code *genadjfpu(code *c, int offset); code *gennop(code *); code *genshift(code *); code *movregconst (code *c , unsigned reg , targ_size_t value , regm_t flags );