* x86 and SPARC: fixed handling 64-bit (qwordbool) values in tcgnotnode (partial fix for Mantis ).

* Moved handling LOC_JUMP locations to helper method of base class, it appears to be the same for all targets.

git-svn-id: trunk@26353 -
This commit is contained in:
sergei 2014-01-02 10:29:44 +00:00
parent e1332304ef
commit 36d0c8a5a7
3 changed files with 67 additions and 46 deletions

View File

@ -109,6 +109,7 @@ interface
tcgnotnode = class(tnotnode)
protected
function handle_locjump: boolean;
procedure second_boolean;virtual;abstract;
{$ifdef SUPPORT_MMX}
procedure second_mmx;virtual;abstract;
@ -131,7 +132,7 @@ implementation
parabase,
pass_2,
ncon,
tgobj,ncgutil,cgobj,cgutils,paramgr,hlcgobj
tgobj,ncgutil,cgobj,cgutils,paramgr,hlcgobj,procinfo
{$ifndef cpu64bitalu}
,cg64f32
{$endif not cpu64bitalu}
@ -557,6 +558,33 @@ implementation
end;
function tcgnotnode.handle_locjump: boolean;
var
hl: tasmlabel;
begin
result:=(left.expectloc=LOC_JUMP);
if result then
begin
hl:=current_procinfo.CurrTrueLabel;
current_procinfo.CurrTrueLabel:=current_procinfo.CurrFalseLabel;
current_procinfo.CurrFalseLabel:=hl;
secondpass(left);
if is_constboolnode(left) then
internalerror(2014010101);
if left.location.loc<>LOC_JUMP then
internalerror(2012081306);
{ This does nothing for LOC_JUMP }
//maketojumpbool(current_asmdata.CurrAsmList,left,lr_load_regvars);
hl:=current_procinfo.CurrTrueLabel;
current_procinfo.CurrTrueLabel:=current_procinfo.CurrFalseLabel;
current_procinfo.CurrFalseLabel:=hl;
location_reset(location,LOC_JUMP,OS_NO);
end;
end;
procedure tcgnotnode.pass_generate_code;
begin
if is_boolean(resultdef) then

View File

@ -253,29 +253,8 @@ implementation
*****************************************************************************}
procedure tsparcnotnode.second_boolean;
var
hl : tasmlabel;
begin
{ if the location is LOC_JUMP, we do the secondpass after the
labels are allocated
}
if left.expectloc=LOC_JUMP then
begin
hl:=current_procinfo.CurrTrueLabel;
current_procinfo.CurrTrueLabel:=current_procinfo.CurrFalseLabel;
current_procinfo.CurrFalseLabel:=hl;
secondpass(left);
if left.location.loc<>LOC_JUMP then
internalerror(2012081306);
maketojumpbool(current_asmdata.CurrAsmList,left,lr_load_regvars);
hl:=current_procinfo.CurrTrueLabel;
current_procinfo.CurrTrueLabel:=current_procinfo.CurrFalseLabel;
current_procinfo.CurrFalseLabel:=hl;
location.loc:=LOC_JUMP;
end
else
if not handle_locjump then
begin
secondpass(left);
case left.location.loc of
@ -290,7 +269,11 @@ implementation
LOC_SUBSETREF, LOC_CSUBSETREF:
begin
hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,left.resultdef,true);
current_asmdata.CurrAsmList.concat(taicpu.op_reg_const_reg(A_SUBcc,left.location.register,0,NR_G0));
if is_64bit(left.resultdef) then
current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_ORcc,
left.location.register64.reglo,left.location.register64.reghi,NR_G0))
else
current_asmdata.CurrAsmList.concat(taicpu.op_reg_const_reg(A_SUBcc,left.location.register,0,NR_G0));
location_reset(location,LOC_FLAGS,OS_NO);
location.resflags:=F_E;
end;

View File

@ -221,28 +221,12 @@ interface
procedure tx86notnode.second_boolean;
var
hl : tasmlabel;
opsize : tcgsize;
hreg: tregister;
begin
opsize:=def_cgsize(resultdef);
if left.expectloc=LOC_JUMP then
begin
location_reset(location,LOC_JUMP,OS_NO);
hl:=current_procinfo.CurrTrueLabel;
current_procinfo.CurrTrueLabel:=current_procinfo.CurrFalseLabel;
current_procinfo.CurrFalseLabel:=hl;
secondpass(left);
if left.location.loc<>LOC_JUMP then
internalerror(2012081307);
maketojumpbool(current_asmdata.CurrAsmList,left,lr_load_regvars);
hl:=current_procinfo.CurrTrueLabel;
current_procinfo.CurrTrueLabel:=current_procinfo.CurrFalseLabel;
current_procinfo.CurrFalseLabel:=hl;
end
else
if not handle_locjump then
begin
{ the second pass could change the location of left }
{ if it is a register variable, so we've to do }
@ -255,18 +239,44 @@ interface
location.resflags:=left.location.resflags;
inverse_flags(location.resflags);
end;
LOC_CREFERENCE,
LOC_REFERENCE:
begin
{$ifndef cpu64bitalu}
if is_64bit(resultdef) then
begin
hreg:=cg.GetIntRegister(current_asmdata.CurrAsmList,OS_32);
tcgx86(cg).make_simple_ref(current_asmdata.CurrAsmList,left.location.reference);
cg.a_load_ref_reg(current_asmdata.CurrAsmList,OS_32,OS_32,left.location.reference,hreg);
inc(left.location.reference.offset,4);
cg.a_op_ref_reg(current_asmdata.CurrAsmList,OP_OR,OS_32,left.location.reference,hreg);
end
else
{$endif cpu64bitalu}
emit_const_ref(A_CMP, TCGSize2Opsize[opsize], 0, left.location.reference);
location_reset(location,LOC_FLAGS,OS_NO);
location.resflags:=F_E;
end;
LOC_CONSTANT,
LOC_REGISTER,
LOC_CREGISTER,
LOC_REFERENCE,
LOC_CREFERENCE,
LOC_SUBSETREG,
LOC_CSUBSETREG,
LOC_SUBSETREF,
LOC_CSUBSETREF :
begin
hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,resultdef,true);
emit_reg_reg(A_TEST,TCGSize2Opsize[opsize],left.location.register,left.location.register);
{$ifndef cpu64bitalu}
if is_64bit(resultdef) then
begin
hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,resultdef,false);
emit_reg_reg(A_OR,S_L,left.location.register64.reghi,left.location.register64.reglo);
end
else
{$endif cpu64bitalu}
begin
hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,resultdef,true);
emit_reg_reg(A_TEST,TCGSize2Opsize[opsize],left.location.register,left.location.register);
end;
location_reset(location,LOC_FLAGS,OS_NO);
location.resflags:=F_E;
end;