mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-16 04:59:25 +02:00
* SPARC: since peephole optimizer recognizes only one conditional branching instruction, generate all branches using A_Bxx opcode, and change it to A_FBxx if necessary when writing assembler. This enables optimization of floating-point branches.
* Assembler reader: rewrote branch condition matching part, don't try to match integer suffixes to floating-point branches and vice versa. git-svn-id: trunk@26290 -
This commit is contained in:
parent
59aa032986
commit
eaba90dda7
@ -1159,13 +1159,8 @@ implementation
|
||||
procedure TCgSparc.a_jmp_flags(list:TAsmList;const f:TResFlags;l:tasmlabel);
|
||||
var
|
||||
ai : taicpu;
|
||||
op : tasmop;
|
||||
begin
|
||||
if f in [F_FE,F_FNE,F_FG,F_FL,F_FGE,F_FLE] then
|
||||
op:=A_FBxx
|
||||
else
|
||||
op:=A_Bxx;
|
||||
ai := Taicpu.op_sym(op,l);
|
||||
ai:=Taicpu.op_sym(A_Bxx,l);
|
||||
ai.SetCondition(flags_to_cond(f));
|
||||
list.Concat(ai);
|
||||
{ Delay slot }
|
||||
|
@ -104,6 +104,12 @@ uses
|
||||
);
|
||||
|
||||
const
|
||||
firstIntCond=C_A;
|
||||
lastIntCond=C_Z;
|
||||
firstFloatCond=C_FE;
|
||||
lastFloatCond=C_FNE;
|
||||
floatAsmConds=[C_FE..C_FNE];
|
||||
|
||||
cond2str:array[TAsmCond] of string[3]=('',
|
||||
'gu','cc','cs','leu','cs','e','g','ge','l','le','leu','cs',
|
||||
'cc','gu','cc','ne','le','l','ge','g','vc','XX',
|
||||
@ -111,15 +117,6 @@ uses
|
||||
'e','g','l','ge','le','ne'
|
||||
);
|
||||
|
||||
const
|
||||
CondAsmOps=2;
|
||||
CondAsmOp:array[0..CondAsmOps-1] of TAsmOp=(
|
||||
A_Bxx,A_FBxx
|
||||
);
|
||||
CondAsmOpStr:array[0..CondAsmOps-1] of string[7]=(
|
||||
'B','FB'
|
||||
);
|
||||
|
||||
|
||||
{*****************************************************************************
|
||||
Flags
|
||||
|
@ -219,6 +219,8 @@ implementation
|
||||
if hp.typ<>ait_instruction then
|
||||
exit;
|
||||
op:=taicpu(hp).opcode;
|
||||
if (op=A_Bxx) and (taicpu(hp).condition in floatAsmConds) then
|
||||
op:=A_FBxx;
|
||||
{ translate pseudoops, this should be move to a separate pass later, so it's done before
|
||||
peephole optimization }
|
||||
case op of
|
||||
|
@ -592,7 +592,8 @@ Interface
|
||||
|
||||
function TSparcReader.is_asmopcode(const s: string):boolean;
|
||||
var
|
||||
cond:TAsmCond;
|
||||
cond,condlo,condhi:TAsmCond;
|
||||
condstr:string[15];
|
||||
Begin
|
||||
{ making s a value parameter would break other assembler readers }
|
||||
is_asmopcode:=false;
|
||||
@ -612,23 +613,31 @@ Interface
|
||||
end;
|
||||
|
||||
{ not found, check branch instructions }
|
||||
if (Upcase(s[1])='B') or
|
||||
((Upcase(s[1])='F') and (Upcase(s[2])='B')) then
|
||||
if (Upcase(s[1])='B') then
|
||||
begin
|
||||
{ we can search here without an extra table which is sorted by string length
|
||||
because we take the whole remaining string without the leading B }
|
||||
if (Upcase(s[1])='F') then
|
||||
actopcode := A_FBxx
|
||||
else
|
||||
actopcode := A_Bxx;
|
||||
for cond:=low(TAsmCond) to high(TAsmCond) do
|
||||
if (Upper(copy(s,2,length(s)-1))=Upper(Cond2Str[cond])) then
|
||||
begin
|
||||
actasmtoken:=AS_OPCODE;
|
||||
actcondition:=cond;
|
||||
is_asmopcode:=true;
|
||||
end;
|
||||
end;
|
||||
condstr:=lower(copy(s,2,maxint));
|
||||
condlo:=firstIntCond;
|
||||
condhi:=lastIntCond;
|
||||
actopcode:=A_Bxx;
|
||||
end
|
||||
else if ((Upcase(s[1])='F') and (Upcase(s[2])='B')) then
|
||||
begin
|
||||
condstr:=lower(copy(s,3,maxint));
|
||||
condlo:=firstFloatCond;
|
||||
condhi:=lastFloatCond;
|
||||
actopcode:=A_FBxx;
|
||||
end
|
||||
else
|
||||
exit;
|
||||
|
||||
for cond:=condlo to condhi do
|
||||
if (condstr=Cond2Str[cond]) then
|
||||
begin
|
||||
actasmtoken:=AS_OPCODE;
|
||||
actcondition:=cond;
|
||||
is_asmopcode:=true;
|
||||
break;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user