diff --git a/compiler/i386/aoptcpu.pas b/compiler/i386/aoptcpu.pas index 07ba868da1..1f28e33efa 100644 --- a/compiler/i386/aoptcpu.pas +++ b/compiler/i386/aoptcpu.pas @@ -40,7 +40,6 @@ unit aoptcpu; procedure PeepHoleOptPass1; override; procedure PeepHoleOptPass2; override; procedure PostPeepHoleOpts; override; - function DoFpuLoadStoreOpt(var p : tai) : boolean; end; Var @@ -58,56 +57,6 @@ unit aoptcpu; { units we should get rid off: } symsym,symconst; - function TCPUAsmoptimizer.DoFpuLoadStoreOpt(var p: tai): boolean; - { returns true if a "continue" should be done after this optimization } - var hp1, hp2: tai; - begin - DoFpuLoadStoreOpt := false; - if (taicpu(p).oper[0]^.typ = top_ref) and - getNextInstruction(p, hp1) and - (hp1.typ = ait_instruction) and - (((taicpu(hp1).opcode = A_FLD) and - (taicpu(p).opcode = A_FSTP)) or - ((taicpu(p).opcode = A_FISTP) and - (taicpu(hp1).opcode = A_FILD))) and - (taicpu(hp1).oper[0]^.typ = top_ref) and - (taicpu(hp1).opsize = taicpu(p).opsize) and - RefsEqual(taicpu(p).oper[0]^.ref^, taicpu(hp1).oper[0]^.ref^) then - begin - { replacing fstp f;fld f by fst f is only valid for extended because of rounding } - if (taicpu(p).opsize=S_FX) and - getNextInstruction(hp1, hp2) and - (hp2.typ = ait_instruction) and - IsExitCode(hp2) and - (taicpu(p).oper[0]^.ref^.base = current_procinfo.FramePointer) and - not(assigned(current_procinfo.procdef.funcretsym) and - (taicpu(p).oper[0]^.ref^.offset < tabstractnormalvarsym(current_procinfo.procdef.funcretsym).localloc.reference.offset)) and - (taicpu(p).oper[0]^.ref^.index = NR_NO) then - begin - asml.remove(p); - asml.remove(hp1); - p.free; - hp1.free; - p := hp2; - removeLastDeallocForFuncRes(p); - doFPULoadStoreOpt := true; - end - (* can't be done because the store operation rounds - else - { fst can't store an extended value! } - if (taicpu(p).opsize <> S_FX) and - (taicpu(p).opsize <> S_IQ) then - begin - if (taicpu(p).opcode = A_FSTP) then - taicpu(p).opcode := A_FST - else taicpu(p).opcode := A_FIST; - asml.remove(hp1); - hp1.free; - end - *) - end; - end; - { converts a TChange variable to a TRegister } function tch2reg(ch: tinschange): tsuperregister; @@ -577,7 +526,7 @@ begin end end; A_FSTP,A_FISTP: - if doFpuLoadStoreOpt(p) then + if OptPass1FSTP(p) then continue; A_LEA: begin @@ -776,7 +725,7 @@ begin if OptPass2Jcc(p) then continue; A_FSTP,A_FISTP: - if DoFpuLoadStoreOpt(p) then + if OptPass1FSTP(p) then continue; A_IMUL: if OptPass2Imul(p) then diff --git a/compiler/x86/aoptx86.pas b/compiler/x86/aoptx86.pas index aa1a30d3c4..6afa3de88c 100644 --- a/compiler/x86/aoptx86.pas +++ b/compiler/x86/aoptx86.pas @@ -71,6 +71,7 @@ unit aoptx86; function OptPass1Sub(var p : tai) : boolean; function OptPass1SHLSAL(var p : tai) : boolean; function OptPass1SETcc(var p: tai): boolean; + function OptPass1FSTP(var p: tai): boolean; function OptPass2MOV(var p : tai) : boolean; function OptPass2Imul(var p : tai) : boolean; @@ -2448,6 +2449,58 @@ unit aoptx86; end; + function TX86AsmOptimizer.OptPass1FSTP(var p: tai): boolean; + { returns true if a "continue" should be done after this optimization } + var + hp1, hp2: tai; + begin + Result := false; + if MatchOpType(taicpu(p),top_ref) and + GetNextInstruction(p, hp1) and + (hp1.typ = ait_instruction) and + (((taicpu(hp1).opcode = A_FLD) and + (taicpu(p).opcode = A_FSTP)) or + ((taicpu(p).opcode = A_FISTP) and + (taicpu(hp1).opcode = A_FILD))) and + MatchOpType(taicpu(hp1),top_ref) and + (taicpu(hp1).opsize = taicpu(p).opsize) and + RefsEqual(taicpu(p).oper[0]^.ref^, taicpu(hp1).oper[0]^.ref^) then + begin + { replacing fstp f;fld f by fst f is only valid for extended because of rounding } + if (taicpu(p).opsize=S_FX) and + GetNextInstruction(hp1, hp2) and + (hp2.typ = ait_instruction) and + IsExitCode(hp2) and + (taicpu(p).oper[0]^.ref^.base = current_procinfo.FramePointer) and + not(assigned(current_procinfo.procdef.funcretsym) and + (taicpu(p).oper[0]^.ref^.offset < tabstractnormalvarsym(current_procinfo.procdef.funcretsym).localloc.reference.offset)) and + (taicpu(p).oper[0]^.ref^.index = NR_NO) then + begin + asml.remove(p); + asml.remove(hp1); + p.free; + hp1.free; + p := hp2; + RemoveLastDeallocForFuncRes(p); + Result := true; + end + (* can't be done because the store operation rounds + else + { fst can't store an extended value! } + if (taicpu(p).opsize <> S_FX) and + (taicpu(p).opsize <> S_IQ) then + begin + if (taicpu(p).opcode = A_FSTP) then + taicpu(p).opcode := A_FST + else taicpu(p).opcode := A_FIST; + asml.remove(hp1); + hp1.free; + end + *) + end; + end; + + function TX86AsmOptimizer.OptPass2MOV(var p : tai) : boolean; var hp1,hp2: tai; diff --git a/compiler/x86_64/aoptcpu.pas b/compiler/x86_64/aoptcpu.pas index 818d3c2353..960144abe4 100644 --- a/compiler/x86_64/aoptcpu.pas +++ b/compiler/x86_64/aoptcpu.pas @@ -118,6 +118,8 @@ uses result:=OptPass1SHLSAL(p); A_SETcc: result:=OptPass1SETcc(p); + A_FSTP,A_FISTP: + result:=OptPass1FSTP(p); end; end; end;