* m68k: completely replaced 64-bit comparison code with a clone of i386 implementation. No optimizations yet, but it already makes system unit about 300 instructions shorter due to changing node location to LOC_JUMP.

* Cleaned up 32-bit comparison code and implemented one of the optimizations (TST instruction for comparison with constant zero which can act directly on references). This makes system unit shorter by about 1000 instructions.

git-svn-id: trunk@28260 -
This commit is contained in:
sergei 2014-07-24 19:44:41 +00:00
parent 86726a5dc8
commit bd5ce35130

View File

@ -32,23 +32,13 @@ interface
type
t68kaddnode = class(tcgaddnode)
private
function cmp64_lt(left_reg,right_reg:tregister64):tregister;
function cmp64_le(left_reg,right_reg:tregister64):tregister;
function cmp64_eq(left_reg,right_reg:tregister64):tregister;
function cmp64_ne(left_reg,right_reg:tregister64):tregister;
function cmp64_ltu(left_reg,right_reg:tregister64):tregister;
function cmp64_leu(left_reg,right_reg:tregister64):tregister;
function getresflags(unsigned: boolean) : tresflags;
function getres64_register(unsigned:boolean;left_reg,right_reg:tregister64):tregister;
protected
procedure second_addfloat;override;
procedure second_cmpfloat;override;
procedure second_cmpordinal;override;
procedure second_cmpsmallset;override;
procedure second_cmp64bit;override;
public
function pass_1:tnode;override;
end;
@ -62,198 +52,12 @@ implementation
cpuinfo,pass_1,pass_2,regvars,
cpupara,cgutils,procinfo,
ncon,nset,
ncgutil,tgobj,rgobj,rgcpu,cgobj,hlcgobj,cg64f32;
ncgutil,tgobj,rgobj,rgcpu,cgobj,cgcpu,hlcgobj,cg64f32;
{*****************************************************************************
Helpers
*****************************************************************************}
function t68kaddnode.cmp64_lt(left_reg,right_reg:tregister64):tregister;
var
labelcmp64_1,labelcmp64_2 : tasmlabel;
tmpreg : tregister;
begin
tmpreg:=cg.getintregister(current_asmdata.currasmlist,OS_INT);
{ load the value for "false" }
cg.a_load_const_reg(current_asmdata.currasmlist,OS_INT,0,tmpreg);
current_asmdata.getjumplabel(labelcmp64_1);
current_asmdata.getjumplabel(labelcmp64_2);
{ check whether left_reg.reghi is less than right_reg.reghi }
current_asmdata.currasmlist.concat(taicpu.op_reg_reg(A_CMP,S_L,right_reg.reghi,left_reg.reghi));
current_asmdata.currasmlist.concat(taicpu.op_cond_sym(A_BXX,C_LT,S_NO,labelcmp64_2));
{ are left_reg.reghi and right_reg.reghi equal? }
current_asmdata.currasmlist.concat(taicpu.op_cond_sym(A_BXX,C_NE,S_NO,labelcmp64_1));
{ is left_reg.reglo less than right_reg.reglo? }
current_asmdata.currasmlist.concat(taicpu.op_reg_reg(A_CMP,S_L,right_reg.reglo,left_reg.reglo));
current_asmdata.currasmlist.concat(taicpu.op_cond_sym(A_BXX,C_CS,S_NO,labelcmp64_2));
current_asmdata.currasmlist.concat(Taicpu.op_sym(A_BRA,S_NO,labelcmp64_1));
cg.a_label(current_asmdata.currasmlist,labelcmp64_2);
{ load the value for "true" }
cg.a_load_const_reg(current_asmdata.currasmlist,OS_INT,1,tmpreg);
cg.a_label(current_asmdata.currasmlist,labelcmp64_1);
result:=tmpreg;
end;
function t68kaddnode.cmp64_le(left_reg,right_reg:tregister64):tregister;
var
labelcmp64_1,labelcmp64_2 : tasmlabel;
tmpreg : tregister;
begin
tmpreg:=cg.getintregister(current_asmdata.currasmlist,OS_INT);
{ load the value for "false" }
cg.a_load_const_reg(current_asmdata.currasmlist,OS_INT,0,tmpreg);
current_asmdata.getjumplabel(labelcmp64_1);
current_asmdata.getjumplabel(labelcmp64_2);
{ check whether right_reg.reghi is less than left_reg.reghi }
current_asmdata.currasmlist.concat(taicpu.op_reg_reg(A_CMP,S_L,left_reg.reghi,right_reg.reghi));
current_asmdata.currasmlist.concat(taicpu.op_cond_sym(A_BXX,C_LT,S_NO,labelcmp64_1));
{ are left_reg.reghi and right_reg.reghi equal? }
current_asmdata.currasmlist.concat(taicpu.op_cond_sym(A_BXX,C_NE,S_NO,labelcmp64_2));
{ is right_reg.reglo less than left_reg.reglo? }
current_asmdata.currasmlist.concat(taicpu.op_reg_reg(A_CMP,S_L,left_reg.reglo,right_reg.reglo));
current_asmdata.currasmlist.concat(taicpu.op_cond_sym(A_BXX,C_CS,S_NO,labelcmp64_1));
cg.a_label(current_asmdata.currasmlist,labelcmp64_2);
{ load the value for "true" }
cg.a_load_const_reg(current_asmdata.currasmlist,OS_INT,1,tmpreg);
cg.a_label(current_asmdata.currasmlist,labelcmp64_1);
result:=tmpreg;
end;
function t68kaddnode.cmp64_eq(left_reg,right_reg:tregister64):tregister;
var
labelcmp64 : tasmlabel;
tmpreg : tregister;
begin
tmpreg:=cg.getintregister(current_asmdata.currasmlist,OS_INT);
current_asmdata.getjumplabel(labelcmp64);
{ load the value for "false" }
cg.a_load_const_reg(current_asmdata.currasmlist,OS_INT,0,tmpreg);
{ is the high order longword equal? }
current_asmdata.currasmlist.concat(taicpu.op_reg_reg(A_CMP,S_L,left_reg.reghi,right_reg.reghi));
current_asmdata.currasmlist.concat(taicpu.op_cond_sym(A_BXX,C_NE,S_NO,labelcmp64));
{ is the low order longword equal? }
current_asmdata.currasmlist.concat(taicpu.op_reg_reg(A_CMP,S_L,left_reg.reglo,right_reg.reglo));
current_asmdata.currasmlist.concat(taicpu.op_cond_sym(A_BXX,C_NE,S_NO,labelcmp64));
{ load the value for "true" }
cg.a_load_const_reg(current_asmdata.currasmlist,OS_INT,1,tmpreg);
cg.a_label(current_asmdata.currasmlist,labelcmp64);
result:=tmpreg;
end;
function t68kaddnode.cmp64_ne(left_reg,right_reg:tregister64):tregister;
var
labelcmp64 : tasmlabel;
tmpreg : tregister;
begin
tmpreg:=cg.getintregister(current_asmdata.currasmlist,OS_INT);
current_asmdata.getjumplabel(labelcmp64);
{ load the value for "true" }
cg.a_load_const_reg(current_asmdata.currasmlist,OS_INT,1,tmpreg);
{ is the high order longword equal? }
current_asmdata.currasmlist.concat(taicpu.op_reg_reg(A_CMP,S_L,left_reg.reghi,right_reg.reghi));
current_asmdata.currasmlist.concat(taicpu.op_cond_sym(A_BXX,C_NE,S_NO,labelcmp64));
{ is the low order longword equal? }
current_asmdata.currasmlist.concat(taicpu.op_reg_reg(A_CMP,S_L,left_reg.reglo,right_reg.reglo));
current_asmdata.currasmlist.concat(taicpu.op_cond_sym(A_BXX,C_NE,S_NO,labelcmp64));
{ load the value for "false" }
cg.a_load_const_reg(current_asmdata.currasmlist,OS_INT,0,tmpreg);
cg.a_label(current_asmdata.currasmlist,labelcmp64);
result:=tmpreg;
end;
function t68kaddnode.cmp64_ltu(left_reg,right_reg:tregister64):tregister;
var
labelcmp64_1,labelcmp64_2 : tasmlabel;
tmpreg : tregister;
begin
tmpreg:=cg.getintregister(current_asmdata.currasmlist,OS_INT);
{ load the value for "false" }
cg.a_load_const_reg(current_asmdata.currasmlist,OS_INT,0,tmpreg);
current_asmdata.getjumplabel(labelcmp64_1);
current_asmdata.getjumplabel(labelcmp64_2);
{ check whether left_reg.reghi is less than right_reg.reghi }
current_asmdata.currasmlist.concat(taicpu.op_reg_reg(A_CMP,S_L,right_reg.reghi,left_reg.reghi));
current_asmdata.currasmlist.concat(taicpu.op_cond_sym(A_BXX,C_CS,S_NO,labelcmp64_2));
{ are left_reg.reghi and right_reg.reghi equal? }
current_asmdata.currasmlist.concat(taicpu.op_cond_sym(A_BXX,C_NE,S_NO,labelcmp64_1));
{ is left_reg.reglo less than right_reg.reglo? }
current_asmdata.currasmlist.concat(taicpu.op_reg_reg(A_CMP,S_L,right_reg.reglo,left_reg.reglo));
current_asmdata.currasmlist.concat(taicpu.op_cond_sym(A_BXX,C_CS,S_NO,labelcmp64_2));
current_asmdata.currasmlist.concat(Taicpu.op_sym(A_BRA,S_NO,labelcmp64_1));
cg.a_label(current_asmdata.currasmlist,labelcmp64_2);
{ load the value for "true" }
cg.a_load_const_reg(current_asmdata.currasmlist,OS_INT,1,tmpreg);
cg.a_label(current_asmdata.currasmlist,labelcmp64_1);
result:=tmpreg;
end;
function t68kaddnode.cmp64_leu(left_reg,right_reg:tregister64):tregister;
var
labelcmp64_1,labelcmp64_2 : tasmlabel;
tmpreg : tregister;
begin
tmpreg:=cg.getintregister(current_asmdata.currasmlist,OS_INT);
{ load the value for "false" }
cg.a_load_const_reg(current_asmdata.currasmlist,OS_INT,0,tmpreg);
current_asmdata.getjumplabel(labelcmp64_1);
current_asmdata.getjumplabel(labelcmp64_2);
{ check whether right_reg.reghi is less than left_reg.reghi }
current_asmdata.currasmlist.concat(taicpu.op_reg_reg(A_CMP,S_L,left_reg.reghi,right_reg.reghi));
current_asmdata.currasmlist.concat(taicpu.op_cond_sym(A_BXX,C_CS,S_NO,labelcmp64_1));
{ are left_reg.reghi and right_reg.reghi equal? }
current_asmdata.currasmlist.concat(taicpu.op_cond_sym(A_BXX,C_NE,S_NO,labelcmp64_2));
{ is right_reg.reglo less than left_reg.reglo? }
current_asmdata.currasmlist.concat(taicpu.op_reg_reg(A_CMP,S_L,left_reg.reglo,right_reg.reglo));
current_asmdata.currasmlist.concat(taicpu.op_cond_sym(A_BXX,C_CS,S_NO,labelcmp64_1));
cg.a_label(current_asmdata.currasmlist,labelcmp64_2);
{ load the value for "true" }
cg.a_load_const_reg(current_asmdata.currasmlist,OS_INT,1,tmpreg);
cg.a_label(current_asmdata.currasmlist,labelcmp64_1);
result:=tmpreg;
end;
function t68kaddnode.getresflags(unsigned : boolean) : tresflags;
begin
case nodetype of
@ -297,66 +101,6 @@ implementation
end;
end;
function t68kaddnode.getres64_register(unsigned:boolean;left_reg,right_reg:tregister64):tregister;
begin
case nodetype of
equaln:
result:=cmp64_eq(left_reg,right_reg);
unequaln:
result:=cmp64_ne(left_reg,right_reg);
else
if not unsigned then
begin
if nf_swapped in flags then
case nodetype of
ltn:
result:=cmp64_lt(right_reg,left_reg);
lten:
result:=cmp64_le(right_reg,left_reg);
gtn:
result:=cmp64_lt(left_reg,right_reg);
gten:
result:=cmp64_le(left_reg,right_reg);
end
else
case nodetype of
ltn:
result:=cmp64_lt(left_reg,right_reg);
lten:
result:=cmp64_le(left_reg,right_reg);
gtn:
result:=cmp64_lt(right_reg,left_reg);
gten:
result:=cmp64_le(right_reg,left_reg);
end;
end
else
begin
if nf_swapped in Flags then
case nodetype of
ltn:
result:=cmp64_ltu(right_reg,left_reg);
lten:
result:=cmp64_leu(right_reg,left_reg);
gtn:
result:=cmp64_ltu(left_reg,right_reg);
gten:
result:=cmp64_leu(left_reg,right_reg);
end
else
case nodetype of
ltn:
result:=cmp64_ltu(left_reg,right_reg);
lten:
result:=cmp64_leu(left_reg,right_reg);
gtn:
result:=cmp64_ltu(right_reg,left_reg);
gten:
result:=cmp64_leu(right_reg,left_reg);
end;
end;
end;
end;
{*****************************************************************************
AddFloat
@ -504,10 +248,40 @@ implementation
tmpreg : tregister;
opsize : topsize;
cmpsize : tcgsize;
href: treference;
begin
{ determine if the comparison will be unsigned }
unsigned:=not(is_signed(left.resultdef)) or
not(is_signed(right.resultdef));
{ this puts constant operand (if any) to the right }
pass_left_right;
{ tentatively assume left size (correct for possible TST/CMPI, will fix later) }
cmpsize:=def_cgsize(left.resultdef);
opsize:=tcgsize2opsize[cmpsize];
{ set result location }
location_reset(location,LOC_JUMP,OS_NO);
location_reset(location,LOC_FLAGS,OS_NO);
location.resflags := getresflags(unsigned);
{ see if we can optimize into TST }
if (right.location.loc=LOC_CONSTANT) and (right.location.value=0) and
((nodetype in [equaln,unequaln]) or (not unsigned)) then
begin
case left.location.loc of
LOC_REFERENCE,
LOC_CREFERENCE:
begin
href:=left.location.reference;
tcg68k(cg).fixref(current_asmdata.CurrAsmList,href);
current_asmdata.CurrAsmList.concat(taicpu.op_ref(A_TST,opsize,href));
location_freetemp(current_asmdata.CurrAsmList,left.location);
end;
else
hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,left.resultdef,true);
current_asmdata.CurrAsmList.concat(taicpu.op_reg(A_TST,opsize,left.location.register));
end;
exit;
end;
{ ToDo : set "allowconstants" to True, but this seems to upset Coldfire
a bit for the CMP instruction => check manual and implement
@ -515,49 +289,8 @@ implementation
{ load values into registers (except constants) }
force_reg_left_right(true, false);
{ determine if the comparison will be unsigned }
unsigned:=not(is_signed(left.resultdef)) or
not(is_signed(right.resultdef));
useconst := false;
// get the constant on the right if there is one
if (left.location.loc = LOC_CONSTANT) then
swapleftright;
// can we use an immediate, or do we have to load the
// constant in a register first?
if (right.location.loc = LOC_CONSTANT) then
begin
{$ifdef extdebug}
if (right.location.size in [OS_64,OS_S64]) and (hi(right.location.value64)<>0) and ((hi(right.location.value64)<>-1) or unsigned) then
internalerror(2002080301);
{$endif extdebug}
if (nodetype in [equaln,unequaln]) then
if (unsigned and
(right.location.value > high(word))) or
(not unsigned and
(longint(right.location.value) < low(smallint)) or
(longint(right.location.value) > high(smallint))) then
{ we can then maybe use a constant in the 'othersigned' case
(the sign doesn't matter for // equal/unequal)}
unsigned := not unsigned;
if (unsigned and
((right.location.value) <= high(word))) or
(not(unsigned) and
(longint(right.location.value) >= low(smallint)) and
(longint(right.location.value) <= high(smallint))) then
useconst := true
else
begin
useconst := false;
tmpreg := cg.getintregister(current_asmdata.CurrAsmList,OS_INT);
cg.a_load_const_reg(current_asmdata.CurrAsmList,OS_INT,
aword(right.location.value),tmpreg);
end
end
else
useconst := false;
location.loc := LOC_FLAGS;
location.resflags := getresflags(unsigned);
if tcgsize2size[right.location.size]=tcgsize2size[left.location.size] then
cmpsize:=left.location.size
else
@ -571,7 +304,7 @@ implementation
internalerror(2013090301);
{ Attention: The RIGHT(!) operand is substracted from and must be a
register! }
if (right.location.loc = LOC_CONSTANT) then
{if (right.location.loc = LOC_CONSTANT) then
if useconst then
current_asmdata.CurrAsmList.concat(taicpu.op_const_reg(A_CMP,opsize,
longint(right.location.value),left.location.register))
@ -580,33 +313,12 @@ implementation
current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_CMP,opsize,
tmpreg,left.location.register));
end
else
else}
current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_CMP,opsize,
right.location.register,left.location.register));
end;
function t68kaddnode.pass_1:tnode;
var
ld,rd : tdef;
begin
result:=inherited pass_1;
{ for 64 bit operations we return the resulting value in a register }
if not assigned(result) then
begin
rd:=right.resultdef;
ld:=left.resultdef;
if (nodetype in [ltn,lten,gtn,gten,equaln,unequaln]) and
(
((ld.typ=orddef) and (torddef(ld).ordtype in [u64bit,s64bit,scurrency])) or
((rd.typ=orddef) and (torddef(rd).ordtype in [u64bit,s64bit,scurrency]))
) then
expectloc:=LOC_REGISTER;
end;
end;
{*****************************************************************************
64-bit
*****************************************************************************}
@ -614,7 +326,64 @@ implementation
procedure t68kaddnode.second_cmp64bit;
var
unsigned : boolean;
tmp_left_reg : tregister;
procedure firstjmp64bitcmp;
var
oldnodetype : tnodetype;
begin
case nodetype of
ltn,gtn:
begin
cg.a_jmp_flags(current_asmdata.CurrAsmList,getresflags(unsigned),current_procinfo.CurrTrueLabel);
{ cheat a little bit for the negative test }
toggleflag(nf_swapped);
cg.a_jmp_flags(current_asmdata.CurrAsmList,getresflags(unsigned),current_procinfo.CurrFalseLabel);
toggleflag(nf_swapped);
end;
lten,gten:
begin
oldnodetype:=nodetype;
if nodetype=lten then
nodetype:=ltn
else
nodetype:=gtn;
cg.a_jmp_flags(current_asmdata.CurrAsmList,getresflags(unsigned),current_procinfo.CurrTrueLabel);
{ cheat for the negative test }
if nodetype=ltn then
nodetype:=gtn
else
nodetype:=ltn;
cg.a_jmp_flags(current_asmdata.CurrAsmList,getresflags(unsigned),current_procinfo.CurrFalseLabel);
nodetype:=oldnodetype;
end;
equaln:
cg.a_jmp_flags(current_asmdata.CurrAsmList,F_NE,current_procinfo.CurrFalseLabel);
unequaln:
cg.a_jmp_flags(current_asmdata.CurrAsmList,F_NE,current_procinfo.CurrTrueLabel);
end;
end;
procedure secondjmp64bitcmp;
begin
case nodetype of
ltn,gtn,lten,gten:
begin
cg.a_jmp_flags(current_asmdata.CurrAsmList,getresflags(true),current_procinfo.CurrTrueLabel);
cg.a_jmp_always(current_asmdata.CurrAsmList,current_procinfo.CurrFalseLabel);
end;
equaln:
begin
cg.a_jmp_flags(current_asmdata.CurrAsmList,F_NE,current_procinfo.CurrFalseLabel);
cg.a_jmp_always(current_asmdata.CurrAsmList,current_procinfo.CurrTrueLabel);
end;
unequaln:
begin
cg.a_jmp_flags(current_asmdata.CurrAsmList,F_NE,current_procinfo.CurrTrueLabel);
cg.a_jmp_always(current_asmdata.CurrAsmList,current_procinfo.CurrFalseLabel);
end;
end;
end;
begin
pass_left_right;
force_reg_left_right(false,false);
@ -622,113 +391,11 @@ implementation
unsigned:=not(is_signed(left.resultdef)) or
not(is_signed(right.resultdef));
location_reset(location,LOC_REGISTER,OS_INT);
location.register:=getres64_register(unsigned,left.location.register64,right.location.register64);
{ keep the below code for now, as we could optimize the =/<> code later
on based on it }
// writeln('second_cmp64bit');
// pass_left_right;
// load_left_right(true,false);
(*
case nodetype of
ltn,lten,
gtn,gten:
begin
emit_cmp64_hi;
firstjmp64bitcmp;
emit_cmp64_lo;
secondjmp64bitcmp;
end;
equaln,unequaln:
begin
// instead of doing a complicated compare, do
// (left.hi xor right.hi) or (left.lo xor right.lo)
// (somewhate optimized so that no superfluous 'mr's are
// generated)
if (left.location.loc = LOC_CONSTANT) then
swapleftright;
if (right.location.loc = LOC_CONSTANT) then
begin
if left.location.loc = LOC_REGISTER then
begin
tempreg64.reglo := left.location.register64.reglo;
tempreg64.reghi := left.location.register64.reghi;
end
else
begin
if (aword(right.location.valueqword) <> 0) then
tempreg64.reglo := cg.getintregister(current_asmdata.CurrAsmList)
else
tempreg64.reglo := left.location.register64.reglo;
if ((right.location.valueqword shr 32) <> 0) then
tempreg64.reghi := cg.getintregister(current_asmdata.CurrAsmList)
else
tempreg64.reghi := left.location.register64.reghi;
end;
if (aword(right.location.valueqword) <> 0) then
{ negative values can be handled using SUB, }
{ positive values < 65535 using XOR. }
if (longint(right.location.valueqword) >= -32767) and
(longint(right.location.valueqword) < 0) then
cg.a_op_const_reg_reg(current_asmdata.CurrAsmList,OP_SUB,OS_INT,
aword(right.location.valueqword),
left.location.register64.reglo,tempreg64.reglo)
else
cg.a_op_const_reg_reg(current_asmdata.CurrAsmList,OP_XOR,OS_INT,
aword(right.location.valueqword),
left.location.register64.reglo,tempreg64.reglo);
if ((right.location.valueqword shr 32) <> 0) then
if (longint(right.location.valueqword shr 32) >= -32767) and
(longint(right.location.valueqword shr 32) < 0) then
cg.a_op_const_reg_reg(current_asmdata.CurrAsmList,OP_SUB,OS_INT,
aword(right.location.valueqword shr 32),
left.location.register64.reghi,tempreg64.reghi)
else
cg.a_op_const_reg_reg(current_asmdata.CurrAsmList,OP_XOR,OS_INT,
aword(right.location.valueqword shr 32),
left.location.register64.reghi,tempreg64.reghi);
end
else
begin
tempreg64.reglo := cg.getintregister(current_asmdata.CurrAsmList);
tempreg64.reghi := cg.getintregister(current_asmdata.CurrAsmList);
cg64.a_op64_reg_reg_reg(current_asmdata.CurrAsmList,OP_XOR,
left.location.register64,right.location.register64,
tempreg64);
end;
cg.a_reg_alloc(current_asmdata.CurrAsmList,R_0);
current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_OR_,R_0,
tempreg64.reglo,tempreg64.reghi));
cg.a_reg_dealloc(current_asmdata.CurrAsmList,R_0);
if (tempreg64.reglo <> left.location.register64.reglo) then
cg.ungetregister(current_asmdata.CurrAsmList,tempreg64.reglo);
if (tempreg64.reghi <> left.location.register64.reghi) then
cg.ungetregister(current_asmdata.CurrAsmList,tempreg64.reghi);
location_reset(location,LOC_FLAGS,OS_NO);
location.resflags := getresflags;
end;
else
internalerror(2002072803);
end;
{ set result location }
{ (emit_compare sets it to LOC_FLAGS for compares, so set the }
{ real location only now) (JM) }
if cmpop and
not(nodetype in [equaln,unequaln]) then
location_reset(location,LOC_JUMP,OS_NO);
*)
// location_reset(location,LOC_JUMP,OS_NO);
// writeln('second_cmp64_exit');
location_reset(location,LOC_JUMP,OS_NO);
current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_CMP,S_L,right.location.register64.reghi,left.location.register64.reghi));
firstjmp64bitcmp;
current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_CMP,S_L,right.location.register64.reglo,left.location.register64.reglo));
secondjmp64bitcmp;
end;