|
@@ -31,7 +31,7 @@ interface
|
|
|
|
|
|
type
|
|
|
|
|
|
- { njvmadd }
|
|
|
+ { tjvmaddnode }
|
|
|
|
|
|
tjvmaddnode = class(tcgaddnode)
|
|
|
protected
|
|
@@ -41,6 +41,7 @@ interface
|
|
|
|
|
|
procedure second_generic_compare;
|
|
|
|
|
|
+ procedure pass_left_right;override;
|
|
|
procedure second_addfloat;override;
|
|
|
procedure second_cmpfloat;override;
|
|
|
procedure second_cmpboolean;override;
|
|
@@ -89,42 +90,53 @@ interface
|
|
|
|
|
|
|
|
|
procedure tjvmaddnode.second_generic_compare;
|
|
|
+ var
|
|
|
+ cmpop: TOpCmp;
|
|
|
begin
|
|
|
pass_left_right;
|
|
|
- if (nf_swapped in flags) then
|
|
|
+ { swap the operands to make it easier for the optimizer to optimize
|
|
|
+ the operand stack slot reloading in case both are in a register }
|
|
|
+ if (left.location.loc in [LOC_REGISTER,LOC_CREGISTER]) and
|
|
|
+ (right.location.loc in [LOC_REGISTER,LOC_CREGISTER]) then
|
|
|
swapleftright;
|
|
|
+ cmpop:=cmpnode2signedtopcmp;
|
|
|
+ if (nf_swapped in flags) then
|
|
|
+ cmpop:=swap_opcmp(cmpop);
|
|
|
location_reset(location,LOC_JUMP,OS_NO);
|
|
|
|
|
|
if left.location.loc in [LOC_REGISTER,LOC_CREGISTER] then
|
|
|
- hlcg.a_cmp_loc_reg_label(current_asmdata.CurrAsmList,left.resultdef,cmpnode2signedtopcmp,right.location,left.location.register,current_procinfo.CurrTrueLabel)
|
|
|
+ hlcg.a_cmp_loc_reg_label(current_asmdata.CurrAsmList,left.resultdef,cmpop,right.location,left.location.register,current_procinfo.CurrTrueLabel)
|
|
|
else case right.location.loc of
|
|
|
LOC_REGISTER,LOC_CREGISTER:
|
|
|
- hlcg.a_cmp_reg_loc_label(current_asmdata.CurrAsmList,left.resultdef,cmpnode2signedtopcmp,right.location.register,left.location,current_procinfo.CurrTrueLabel);
|
|
|
+ hlcg.a_cmp_reg_loc_label(current_asmdata.CurrAsmList,left.resultdef,cmpop,right.location.register,left.location,current_procinfo.CurrTrueLabel);
|
|
|
LOC_REFERENCE,LOC_CREFERENCE:
|
|
|
- hlcg.a_cmp_ref_loc_label(current_asmdata.CurrAsmList,left.resultdef,cmpnode2signedtopcmp,right.location.reference,left.location,current_procinfo.CurrTrueLabel);
|
|
|
+ hlcg.a_cmp_ref_loc_label(current_asmdata.CurrAsmList,left.resultdef,cmpop,right.location.reference,left.location,current_procinfo.CurrTrueLabel);
|
|
|
LOC_CONSTANT:
|
|
|
- hlcg.a_cmp_const_loc_label(current_asmdata.CurrAsmList,left.resultdef,cmpnode2signedtopcmp,right.location.value,left.location,current_procinfo.CurrTrueLabel);
|
|
|
+ hlcg.a_cmp_const_loc_label(current_asmdata.CurrAsmList,left.resultdef,cmpop,right.location.value,left.location,current_procinfo.CurrTrueLabel);
|
|
|
else
|
|
|
internalerror(2011010413);
|
|
|
end;
|
|
|
hlcg.a_jmp_always(current_asmdata.CurrAsmList,current_procinfo.CurrFalseLabel);
|
|
|
end;
|
|
|
|
|
|
+ procedure tjvmaddnode.pass_left_right;
|
|
|
+ begin
|
|
|
+ swapleftright;
|
|
|
+ inherited pass_left_right;
|
|
|
+ end;
|
|
|
+
|
|
|
|
|
|
procedure tjvmaddnode.second_addfloat;
|
|
|
var
|
|
|
op : TAsmOp;
|
|
|
+ commutative : boolean;
|
|
|
begin
|
|
|
pass_left_right;
|
|
|
- if (nf_swapped in flags) then
|
|
|
- swapleftright;
|
|
|
-
|
|
|
- thlcgjvm(hlcg).a_load_loc_stack(current_asmdata.CurrAsmList,left.resultdef,left.location);
|
|
|
- thlcgjvm(hlcg).a_load_loc_stack(current_asmdata.CurrAsmList,right.resultdef,right.location);
|
|
|
|
|
|
location_reset(location,LOC_FPUREGISTER,def_cgsize(resultdef));
|
|
|
location.register:=hlcg.getfpuregister(current_asmdata.CurrAsmList,resultdef);
|
|
|
|
|
|
+ commutative:=false;
|
|
|
case nodetype of
|
|
|
addn :
|
|
|
begin
|
|
@@ -132,6 +144,7 @@ interface
|
|
|
op:=a_dadd
|
|
|
else
|
|
|
op:=a_fadd;
|
|
|
+ commutative:=true;
|
|
|
end;
|
|
|
muln :
|
|
|
begin
|
|
@@ -139,6 +152,7 @@ interface
|
|
|
op:=a_dmul
|
|
|
else
|
|
|
op:=a_fmul;
|
|
|
+ commutative:=true;
|
|
|
end;
|
|
|
subn :
|
|
|
begin
|
|
@@ -158,6 +172,19 @@ interface
|
|
|
internalerror(2011010402);
|
|
|
end;
|
|
|
|
|
|
+ { swap the operands to make it easier for the optimizer to optimize
|
|
|
+ the operand stack slot reloading (non-commutative operations must
|
|
|
+ always be in the correct order though) }
|
|
|
+ if (commutative and
|
|
|
+ (left.location.loc in [LOC_FPUREGISTER,LOC_CFPUREGISTER]) and
|
|
|
+ (right.location.loc in [LOC_FPUREGISTER,LOC_CFPUREGISTER])) or
|
|
|
+ (not commutative and
|
|
|
+ (nf_swapped in flags)) then
|
|
|
+ swapleftright;
|
|
|
+
|
|
|
+ thlcgjvm(hlcg).a_load_loc_stack(current_asmdata.CurrAsmList,left.resultdef,left.location);
|
|
|
+ thlcgjvm(hlcg).a_load_loc_stack(current_asmdata.CurrAsmList,right.resultdef,right.location);
|
|
|
+
|
|
|
current_asmdata.CurrAsmList.concat(taicpu.op_none(op));
|
|
|
thlcgjvm(hlcg).decstack(current_asmdata.CurrAsmList,1+ord(location.size=OS_F64));
|
|
|
{ could be optimized in the future by keeping the results on the stack,
|
|
@@ -171,10 +198,17 @@ interface
|
|
|
procedure tjvmaddnode.second_cmpfloat;
|
|
|
var
|
|
|
op : tasmop;
|
|
|
+ cmpop: TOpCmp;
|
|
|
begin
|
|
|
pass_left_right;
|
|
|
- if (nf_swapped in flags) then
|
|
|
+ { swap the operands to make it easier for the optimizer to optimize
|
|
|
+ the operand stack slot reloading in case both are in a register }
|
|
|
+ if (left.location.loc in [LOC_FPUREGISTER,LOC_CFPUREGISTER]) and
|
|
|
+ (right.location.loc in [LOC_FPUREGISTER,LOC_CFPUREGISTER]) then
|
|
|
swapleftright;
|
|
|
+ cmpop:=cmpnode2signedtopcmp;
|
|
|
+ if (nf_swapped in flags) then
|
|
|
+ cmpop:=swap_opcmp(cmpop);
|
|
|
location_reset(location,LOC_JUMP,OS_NO);
|
|
|
|
|
|
thlcgjvm(hlcg).a_load_loc_stack(current_asmdata.CurrAsmList,left.resultdef,left.location);
|
|
@@ -195,7 +229,7 @@ interface
|
|
|
current_asmdata.CurrAsmList.concat(taicpu.op_none(op));
|
|
|
thlcgjvm(hlcg).decstack(current_asmdata.CurrAsmList,(1+ord(left.location.size=OS_F64))*2-1);
|
|
|
|
|
|
- current_asmdata.CurrAsmList.concat(taicpu.op_sym(opcmp2if[cmpnode2signedtopcmp],current_procinfo.CurrTrueLabel));
|
|
|
+ current_asmdata.CurrAsmList.concat(taicpu.op_sym(opcmp2if[cmpop],current_procinfo.CurrTrueLabel));
|
|
|
thlcgjvm(hlcg).decstack(current_asmdata.CurrAsmList,1);
|
|
|
hlcg.a_jmp_always(current_asmdata.CurrAsmList,current_procinfo.CurrFalseLabel);
|
|
|
end;
|