+ MIPS: support floating point conditions in its emulated flags, on MIPS4+ convert such flags to registers using conditional move instructions (i.e. without branching). For older cores generated code remains the same.

git-svn-id: trunk@28535 -
This commit is contained in:
sergei 2014-08-29 18:18:17 +00:00
parent 5a7b1f00cf
commit d9a7d28838
2 changed files with 51 additions and 23 deletions

View File

@ -1071,7 +1071,28 @@ end;
procedure TCGMIPS.a_jmp_flags(list: tasmlist; const f: TResFlags; l: tasmlabel);
var
ai: taicpu;
begin
case f.reg1 of
NR_FCC0..NR_FCC7:
begin
if (f.reg1=NR_FCC0) then
ai:=taicpu.op_sym(A_BC,l)
else
ai:=taicpu.op_reg_sym(A_BC,f.reg1,l);
list.concat(ai);
{ delay slot }
list.concat(taicpu.op_none(A_NOP));
case f.cond of
OC_NE: ai.SetCondition(C_COP1TRUE);
OC_EQ: ai.SetCondition(C_COP1FALSE);
else
InternalError(2014082901);
end;
exit;
end;
end;
if f.use_const then
a_cmp_const_reg_label(list,OS_INT,f.cond,f.value,f.reg1,l)
else
@ -1083,7 +1104,33 @@ procedure TCGMIPS.g_flags2reg(list: tasmlist; size: tcgsize; const f: tresflags;
var
left,right: tregister;
unsigned: boolean;
hl: tasmlabel;
begin
case f.reg1 of
NR_FCC0..NR_FCC7:
begin
if (current_settings.cputype>=cpu_mips4) then
begin
a_load_const_reg(list,size,1,reg);
case f.cond of
OC_NE: list.concat(taicpu.op_reg_reg_reg(A_MOVF,reg,NR_R0,f.reg1));
OC_EQ: list.concat(taicpu.op_reg_reg_reg(A_MOVT,reg,NR_R0,f.reg1));
else
InternalError(2014082902);
end;
end
else
begin
{ TODO: still possible to do branchless by extracting appropriate bit from FCSR? }
current_asmdata.getjumplabel(hl);
a_load_const_reg(list,size,1,reg);
a_jmp_flags(list,f,hl);
a_load_const_reg(list,size,0,reg);
a_label(list,hl);
end;
exit;
end;
end;
if (f.cond in [OC_EQ,OC_NE]) then
begin
left:=reg;

View File

@ -46,7 +46,6 @@ type
procedure second_cmpordinal; override;
procedure second_addordinal; override;
public
function pass_1: tnode; override;
function use_generic_mul32to64: boolean; override;
end;
@ -185,21 +184,6 @@ begin
end;
function tmipsaddnode.pass_1 : tnode;
begin
result:=inherited pass_1;
if not(assigned(result)) then
begin
if (nodetype in [ltn,lten,gtn,gten,equaln,unequaln]) then
begin
if (left.resultdef.typ=floatdef) or (right.resultdef.typ=floatdef) then
expectloc:=LOC_JUMP;
end;
end;
end;
procedure tmipsaddnode.second_addfloat;
var
op: TAsmOp;
@ -273,7 +257,7 @@ begin
hlcg.location_force_fpureg(current_asmdata.CurrAsmList, left.location, left.resultdef, True);
hlcg.location_force_fpureg(current_asmdata.CurrAsmList, right.location, right.resultdef, True);
location_reset(location, LOC_JUMP, OS_NO);
location_reset(location, LOC_FLAGS, OS_NO);
op:=ops_cmpfloat[left.location.size=OS_F64,nodetype];
@ -289,14 +273,11 @@ begin
end;
current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(op,lreg,rreg));
ai:=taicpu.op_sym(A_BC,current_procinfo.CurrTrueLabel);
location.resflags.reg1:=NR_FCC0;
if (nodetype=unequaln) then
ai.SetCondition(C_COP1FALSE)
location.resflags.cond:=OC_EQ
else
ai.SetCondition(C_COP1TRUE);
current_asmdata.CurrAsmList.concat(ai);
current_asmdata.CurrAsmList.concat(TAiCpu.Op_none(A_NOP));
cg.a_jmp_always(current_asmdata.CurrAsmList,current_procinfo.CurrFalseLabel);
location.resflags.cond:=OC_NE;
end;