|
@@ -34,7 +34,7 @@ interface
|
|
|
procedure pass_2;override;
|
|
|
private
|
|
|
procedure pass_left_and_right;
|
|
|
- procedure load_left_right(cmpop: boolean);
|
|
|
+ procedure load_left_right(cmpop, load_constants: boolean);
|
|
|
procedure clear_left_right(cmpop: boolean);
|
|
|
function getresflags : tresflags;
|
|
|
procedure emit_compare(unsigned : boolean);
|
|
@@ -44,7 +44,7 @@ interface
|
|
|
{$ifdef SUPPORT_MMX}
|
|
|
procedure second_addmmx;
|
|
|
{$endif SUPPORT_MMX}
|
|
|
- procedure second_add64bit; virtual; abstract;
|
|
|
+ procedure second_add64bit;
|
|
|
end;
|
|
|
|
|
|
implementation
|
|
@@ -95,30 +95,43 @@ interface
|
|
|
end;
|
|
|
|
|
|
|
|
|
- procedure tppcaddnode.load_left_right(cmpop: boolean);
|
|
|
- begin
|
|
|
- case left.location.loc of
|
|
|
- LOC_REGISTER:
|
|
|
- if not cmpop then
|
|
|
- location.register := left.location.register;
|
|
|
- LOC_REFERENCE,LOC_CREFERENCE:
|
|
|
- begin
|
|
|
- location_force_reg(exprasmlist,left.location,def_cgsize(left.resulttype.def),false);
|
|
|
- if not cmpop then
|
|
|
- location.register := left.location.register;
|
|
|
- end;
|
|
|
- end;
|
|
|
- case right.location.loc of
|
|
|
- LOC_REGISTER:
|
|
|
- if not cmpop then
|
|
|
- location.register := right.location.register;
|
|
|
- LOC_REFERENCE,LOC_CREFERENCE:
|
|
|
- begin
|
|
|
- location_force_reg(exprasmlist,right.location,def_cgsize(right.resulttype.def),false);
|
|
|
+ procedure tppcaddnode.load_left_right(cmpop, load_constants: boolean);
|
|
|
+
|
|
|
+ procedure load_node(var n: tnode);
|
|
|
+ begin
|
|
|
+ case n.location.loc of
|
|
|
+ LOC_REGISTER:
|
|
|
if not cmpop then
|
|
|
- location.register := right.location.register;
|
|
|
- end;
|
|
|
+ begin
|
|
|
+ location.register := n.location.register;
|
|
|
+ if is_64bitint(n.resulttype.def) then
|
|
|
+ location.registerhigh := n.location.registerhigh;
|
|
|
+ end;
|
|
|
+ LOC_REFERENCE,LOC_CREFERENCE:
|
|
|
+ begin
|
|
|
+ location_force_reg(exprasmlist,n.location,def_cgsize(n.resulttype.def),false);
|
|
|
+ if not cmpop then
|
|
|
+ location.register := n.location.register;
|
|
|
+ if is_64bitint(n.resulttype.def) then
|
|
|
+ location.registerhigh := n.location.registerhigh;
|
|
|
+ end;
|
|
|
+ LOC_CONSTANT:
|
|
|
+ begin
|
|
|
+ if load_constants then
|
|
|
+ begin
|
|
|
+ location_force_reg(exprasmlist,n.location,def_cgsize(n.resulttype.def),false);
|
|
|
+ if not cmpop then
|
|
|
+ location.register := n.location.register;
|
|
|
+ if is_64bitint(n.resulttype.def) then
|
|
|
+ location.registerhigh := n.location.registerhigh;
|
|
|
+ end;
|
|
|
+ end;
|
|
|
+ end;
|
|
|
end;
|
|
|
+
|
|
|
+ begin
|
|
|
+ load_node(left);
|
|
|
+ load_node(right);
|
|
|
end;
|
|
|
|
|
|
|
|
@@ -127,11 +140,19 @@ interface
|
|
|
if (right.location.loc in [LOC_REGISTER,LOC_FPUREGISTER]) and
|
|
|
(cmpop or
|
|
|
(location.register <> right.location.register)) then
|
|
|
- rg.ungetregister(exprasmlist,right.location.register);
|
|
|
+ begin
|
|
|
+ rg.ungetregister(exprasmlist,right.location.register);
|
|
|
+ if is_64bitint(right.resulttype.def) then
|
|
|
+ rg.ungetregister(exprasmlist,right.location.registerhigh);
|
|
|
+ end;
|
|
|
if (left.location.loc in [LOC_REGISTER,LOC_FPUREGISTER]) and
|
|
|
(cmpop or
|
|
|
(location.register <> left.location.register)) then
|
|
|
- rg.ungetregister(exprasmlist,left.location.register);
|
|
|
+ begin
|
|
|
+ rg.ungetregister(exprasmlist,left.location.register);
|
|
|
+ if is_64bitint(left.resulttype.def) then
|
|
|
+ rg.ungetregister(exprasmlist,left.location.registerhigh);
|
|
|
+ end;
|
|
|
end;
|
|
|
|
|
|
|
|
@@ -162,6 +183,7 @@ interface
|
|
|
end
|
|
|
end;
|
|
|
|
|
|
+
|
|
|
procedure tppcaddnode.emit_compare(unsigned: boolean);
|
|
|
var
|
|
|
op : tasmop;
|
|
@@ -177,13 +199,12 @@ interface
|
|
|
begin
|
|
|
if (nodetype in [equaln,unequaln]) then
|
|
|
if (unsigned and
|
|
|
- (right.location.value > high(aword))) or
|
|
|
+ (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 if we use a constant
|
|
|
- // for the 'othersigned' case and the sign doesn't matter in
|
|
|
- // this case
|
|
|
+ // 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
|
|
@@ -308,7 +329,7 @@ interface
|
|
|
else
|
|
|
location_reset(location,LOC_FLAGS,OS_NO);
|
|
|
|
|
|
- load_left_right(cmpop);
|
|
|
+ load_left_right(cmpop,false);
|
|
|
|
|
|
if (left.location.loc = LOC_CONSTANT) then
|
|
|
swapleftright;
|
|
@@ -507,7 +528,7 @@ interface
|
|
|
else
|
|
|
location_reset(location,LOC_FLAGS,OS_NO);
|
|
|
|
|
|
- load_left_right(cmpop);
|
|
|
+ load_left_right(cmpop,false);
|
|
|
|
|
|
if not(cmpop) and
|
|
|
(location.register = R_NO) then
|
|
@@ -559,14 +580,13 @@ interface
|
|
|
right.location.value := not(right.location.value)
|
|
|
else
|
|
|
opdone := true
|
|
|
+ else if (left.location.loc=LOC_CONSTANT) then
|
|
|
+ left.location.value := not(left.location.value)
|
|
|
else
|
|
|
- if (left.location.loc=LOC_CONSTANT) then
|
|
|
- left.location.value := not(left.location.value)
|
|
|
- else
|
|
|
- begin
|
|
|
- swapleftright;
|
|
|
- opdone := true;
|
|
|
- end;
|
|
|
+ begin
|
|
|
+ swapleftright;
|
|
|
+ opdone := true;
|
|
|
+ end;
|
|
|
if opdone then
|
|
|
begin
|
|
|
if left.location.loc = LOC_CONSTANT then
|
|
@@ -650,35 +670,60 @@ interface
|
|
|
Add64bit
|
|
|
*****************************************************************************}
|
|
|
|
|
|
-(*
|
|
|
- procedure ti386addnode.second_add64bit;
|
|
|
+ procedure tppcaddnode.second_add64bit;
|
|
|
var
|
|
|
op : TOpCG;
|
|
|
op1,op2 : TAsmOp;
|
|
|
- opsize : TOpSize;
|
|
|
- hregister,
|
|
|
- hregister2 : tregister;
|
|
|
- href : treference;
|
|
|
hl4 : tasmlabel;
|
|
|
- mboverflow,
|
|
|
cmpop,
|
|
|
unsigned : boolean;
|
|
|
|
|
|
- procedure firstjmp64bitcmp;
|
|
|
+
|
|
|
+ procedure emit_cmp64_hi;
|
|
|
|
|
|
var
|
|
|
- oldnodetype : tnodetype;
|
|
|
+ oldleft, oldright: tlocation;
|
|
|
+ begin
|
|
|
+ // put the high part of the location in the low part
|
|
|
+ location_copy(oldleft,left.location);
|
|
|
+ location_copy(oldright,right.location);
|
|
|
+ if left.location.loc = LOC_CONSTANT then
|
|
|
+ left.location.value := left.location.value shr 32
|
|
|
+ else
|
|
|
+ left.location.registerlow := left.location.registerhigh;
|
|
|
+ if right.location.loc = LOC_CONSTANT then
|
|
|
+ right.location.value := right.location.value shr 32
|
|
|
+ else
|
|
|
+ right.location.registerlow := right.location.registerhigh;
|
|
|
+
|
|
|
+ // and call the normal emit_compare
|
|
|
+ emit_compare(unsigned);
|
|
|
+ location_copy(left.location,oldleft);
|
|
|
+ location_copy(right.location,oldright);
|
|
|
+ end;
|
|
|
|
|
|
+
|
|
|
+ procedure emit_cmp64_lo;
|
|
|
+
|
|
|
+ begin
|
|
|
+ emit_compare(true);
|
|
|
+ end;
|
|
|
+
|
|
|
+
|
|
|
+ procedure firstjmp64bitcmp;
|
|
|
+
|
|
|
+ var
|
|
|
+ oldnodetype: tnodetype;
|
|
|
begin
|
|
|
load_all_regvars(exprasmlist);
|
|
|
{ the jump the sequence is a little bit hairy }
|
|
|
case nodetype of
|
|
|
ltn,gtn:
|
|
|
begin
|
|
|
- emitjmp(flags_to_cond(getresflags(unsigned)),truelabel);
|
|
|
+ cg.a_jmp_flags(exprasmlist,getresflags,truelabel);
|
|
|
{ cheat a little bit for the negative test }
|
|
|
toggleflag(nf_swaped);
|
|
|
- emitjmp(flags_to_cond(getresflags(unsigned)),falselabel);
|
|
|
+ cg.a_jmp_flags(exprasmlist,getresflags,falselabel);
|
|
|
toggleflag(nf_swaped);
|
|
|
end;
|
|
|
lten,gten:
|
|
@@ -688,19 +733,27 @@ interface
|
|
|
nodetype:=ltn
|
|
|
else
|
|
|
nodetype:=gtn;
|
|
|
- emitjmp(flags_to_cond(getresflags(unsigned)),truelabel);
|
|
|
+ cg.a_jmp_flags(exprasmlist,getresflags,truelabel);
|
|
|
{ cheat for the negative test }
|
|
|
if nodetype=ltn then
|
|
|
nodetype:=gtn
|
|
|
else
|
|
|
nodetype:=ltn;
|
|
|
- emitjmp(flags_to_cond(getresflags(unsigned)),falselabel);
|
|
|
+ cg.a_jmp_flags(exprasmlist,getresflags,falselabel);
|
|
|
nodetype:=oldnodetype;
|
|
|
end;
|
|
|
equaln:
|
|
|
- emitjmp(C_NE,falselabel);
|
|
|
+ begin
|
|
|
+ nodetype := unequaln;
|
|
|
+ cg.a_jmp_flags(exprasmlist,getresflags,falselabel);
|
|
|
+ nodetype := equaln;
|
|
|
+ end;
|
|
|
unequaln:
|
|
|
- emitjmp(C_NE,truelabel);
|
|
|
+ begin
|
|
|
+ nodetype := equaln;
|
|
|
+ cg.a_jmp_flags(exprasmlist,getresflags,truelabel);
|
|
|
+ nodetype := unequaln;
|
|
|
+ end;
|
|
|
end;
|
|
|
end;
|
|
|
|
|
@@ -714,17 +767,19 @@ interface
|
|
|
begin
|
|
|
{ the comparisaion of the low dword have to be }
|
|
|
{ always unsigned! }
|
|
|
- emitjmp(flags_to_cond(getresflags(true)),truelabel);
|
|
|
+ cg.a_jmp_flags(exprasmlist,getresflags,truelabel);
|
|
|
cg.a_jmp_always(exprasmlist,falselabel);
|
|
|
end;
|
|
|
equaln:
|
|
|
begin
|
|
|
- emitjmp(C_NE,falselabel);
|
|
|
+ nodetype := unequaln;
|
|
|
+ cg.a_jmp_flags(exprasmlist,getresflags,falselabel);
|
|
|
cg.a_jmp_always(exprasmlist,truelabel);
|
|
|
+ nodetype := equaln;
|
|
|
end;
|
|
|
unequaln:
|
|
|
begin
|
|
|
- emitjmp(C_NE,truelabel);
|
|
|
+ cg.a_jmp_flags(exprasmlist,getresflags,truelabel);
|
|
|
cg.a_jmp_always(exprasmlist,falselabel);
|
|
|
end;
|
|
|
end;
|
|
@@ -735,11 +790,7 @@ interface
|
|
|
|
|
|
pass_left_and_right;
|
|
|
|
|
|
- op1:=A_NONE;
|
|
|
- op2:=A_NONE;
|
|
|
- mboverflow:=false;
|
|
|
cmpop:=false;
|
|
|
- opsize:=S_L;
|
|
|
unsigned:=((left.resulttype.def.deftype=orddef) and
|
|
|
(torddef(left.resulttype.def).typ=u64bit)) or
|
|
|
((right.resulttype.def.deftype=orddef) and
|
|
@@ -748,14 +799,10 @@ interface
|
|
|
addn :
|
|
|
begin
|
|
|
op:=OP_ADD;
|
|
|
- mboverflow:=true;
|
|
|
end;
|
|
|
subn :
|
|
|
begin
|
|
|
op:=OP_SUB;
|
|
|
- op1:=A_SUB;
|
|
|
- op2:=A_SBB;
|
|
|
- mboverflow:=true;
|
|
|
end;
|
|
|
ltn,lten,
|
|
|
gtn,gten,
|
|
@@ -776,163 +823,86 @@ interface
|
|
|
internalerror(200109051);
|
|
|
end;
|
|
|
else
|
|
|
- CGMessage(type_e_mismatch);
|
|
|
+ internalerror(2002072705);
|
|
|
end;
|
|
|
|
|
|
- { left and right no register? }
|
|
|
- { then one must be demanded }
|
|
|
- if (left.location.loc<>LOC_REGISTER) then
|
|
|
- begin
|
|
|
- if (right.location.loc<>LOC_REGISTER) then
|
|
|
- begin
|
|
|
- { we can reuse a CREGISTER for comparison }
|
|
|
- if not((left.location.loc=LOC_CREGISTER) and cmpop) then
|
|
|
- begin
|
|
|
- if (left.location.loc<>LOC_CREGISTER) then
|
|
|
- begin
|
|
|
- location_freetemp(exprasmlist,left.location);
|
|
|
- location_release(exprasmlist,left.location);
|
|
|
- end;
|
|
|
- hregister:=rg.getregisterint(exprasmlist);
|
|
|
- hregister2:=rg.getregisterint(exprasmlist);
|
|
|
- cg64.a_load64_loc_reg(exprasmlist,left.location,joinreg64(hregister,hregister2));
|
|
|
- location_reset(left.location,LOC_REGISTER,OS_64);
|
|
|
- left.location.registerlow:=hregister;
|
|
|
- left.location.registerhigh:=hregister2;
|
|
|
- end;
|
|
|
- end
|
|
|
- else
|
|
|
- begin
|
|
|
- location_swap(left.location,right.location);
|
|
|
- toggleflag(nf_swaped);
|
|
|
- end;
|
|
|
- end;
|
|
|
+ { set result location }
|
|
|
+ if not cmpop then
|
|
|
+ location_reset(location,LOC_REGISTER,def_cgsize(resulttype.def))
|
|
|
+ else
|
|
|
+ location_reset(location,LOC_JUMP,OS_NO);
|
|
|
|
|
|
- { at this point, left.location.loc should be LOC_REGISTER }
|
|
|
- if right.location.loc=LOC_REGISTER then
|
|
|
- begin
|
|
|
- { when swapped another result register }
|
|
|
- if (nodetype=subn) and (nf_swaped in flags) then
|
|
|
- begin
|
|
|
- cg64.a_op64_reg_reg(exprasmlist,op,
|
|
|
- left.location.register64,
|
|
|
- right.location.register64);
|
|
|
- location_swap(left.location,right.location);
|
|
|
- toggleflag(nf_swaped);
|
|
|
- end
|
|
|
- else if cmpop then
|
|
|
- begin
|
|
|
- emit_reg_reg(A_CMP,S_L,right.location.registerhigh,left.location.registerhigh);
|
|
|
- firstjmp64bitcmp;
|
|
|
- emit_reg_reg(A_CMP,S_L,right.location.registerlow,left.location.registerlow);
|
|
|
- secondjmp64bitcmp;
|
|
|
- end
|
|
|
- else
|
|
|
- begin
|
|
|
- cg64.a_op64_reg_reg(exprasmlist,op,
|
|
|
- right.location.register64,
|
|
|
- left.location.register64);
|
|
|
- end;
|
|
|
- location_release(exprasmlist,right.location);
|
|
|
- end
|
|
|
- else
|
|
|
- begin
|
|
|
- { right.location<>LOC_REGISTER }
|
|
|
- if (nodetype=subn) and (nf_swaped in flags) then
|
|
|
- begin
|
|
|
- rg.getexplicitregisterint(exprasmlist,R_EDI);
|
|
|
- cg64.a_load64low_loc_reg(exprasmlist,right.location,R_EDI);
|
|
|
- emit_reg_reg(op1,opsize,left.location.registerlow,R_EDI);
|
|
|
- emit_reg_reg(A_MOV,opsize,R_EDI,left.location.registerlow);
|
|
|
- cg64.a_load64high_loc_reg(exprasmlist,right.location,R_EDI);
|
|
|
- { the carry flag is still ok }
|
|
|
- emit_reg_reg(op2,opsize,left.location.registerhigh,R_EDI);
|
|
|
- emit_reg_reg(A_MOV,opsize,R_EDI,left.location.registerhigh);
|
|
|
- rg.ungetregisterint(exprasmlist,R_EDI);
|
|
|
- if right.location.loc<>LOC_CREGISTER then
|
|
|
- begin
|
|
|
- location_freetemp(exprasmlist,right.location);
|
|
|
- location_release(exprasmlist,right.location);
|
|
|
- end;
|
|
|
- end
|
|
|
- else if cmpop then
|
|
|
- begin
|
|
|
- case right.location.loc of
|
|
|
- LOC_CREGISTER :
|
|
|
- begin
|
|
|
- emit_reg_reg(A_CMP,S_L,right.location.registerhigh,left.location.registerhigh);
|
|
|
- firstjmp64bitcmp;
|
|
|
- emit_reg_reg(A_CMP,S_L,right.location.registerlow,left.location.registerlow);
|
|
|
- secondjmp64bitcmp;
|
|
|
- end;
|
|
|
- LOC_CREFERENCE,
|
|
|
- LOC_REFERENCE :
|
|
|
- begin
|
|
|
- href:=right.location.reference;
|
|
|
- inc(href.offset,4);
|
|
|
- emit_ref_reg(A_CMP,S_L,href,left.location.registerhigh);
|
|
|
- firstjmp64bitcmp;
|
|
|
- emit_ref_reg(A_CMP,S_L,right.location.reference,left.location.registerlow);
|
|
|
- secondjmp64bitcmp;
|
|
|
- cg.a_jmp_always(exprasmlist,falselabel);
|
|
|
- location_freetemp(exprasmlist,right.location);
|
|
|
- location_release(exprasmlist,right.location);
|
|
|
- end;
|
|
|
- LOC_CONSTANT :
|
|
|
- begin
|
|
|
- exprasmlist.concat(taicpu.op_const_reg(A_CMP,S_L,right.location.valuehigh,left.location.registerhigh));
|
|
|
- firstjmp64bitcmp;
|
|
|
- exprasmlist.concat(taicpu.op_const_reg(A_CMP,S_L,right.location.valuelow,left.location.registerlow));
|
|
|
- secondjmp64bitcmp;
|
|
|
- end;
|
|
|
- else
|
|
|
- internalerror(200203282);
|
|
|
- end;
|
|
|
- end
|
|
|
|
|
|
- else
|
|
|
- begin
|
|
|
- cg64.a_op64_loc_reg(exprasmlist,op,right.location,
|
|
|
- left.location.register64);
|
|
|
- if (right.location.loc<>LOC_CREGISTER) then
|
|
|
- begin
|
|
|
- location_freetemp(exprasmlist,right.location);
|
|
|
- location_release(exprasmlist,right.location);
|
|
|
- end;
|
|
|
- end;
|
|
|
- end;
|
|
|
+ load_left_right(cmpop,(cs_check_overflow in aktlocalswitches) and
|
|
|
+ (nodetype in [addn,subn]));
|
|
|
|
|
|
- if (left.location.loc<>LOC_CREGISTER) and cmpop then
|
|
|
- begin
|
|
|
- location_freetemp(exprasmlist,left.location);
|
|
|
- location_release(exprasmlist,left.location);
|
|
|
- end;
|
|
|
+ // can't do much with a constant on the left side here
|
|
|
+ if (nodetype = subn) then
|
|
|
+ begin
|
|
|
+ if (nf_swaped in flags) then
|
|
|
+ swapleftright;
|
|
|
+ if left.location.loc = LOC_CONSTANT then
|
|
|
+ begin
|
|
|
+ location_force_reg(exprasmlist,left.location,
|
|
|
+ def_cgsize(left.resulttype.def),false);
|
|
|
+ location.register64 := left.location.register64;
|
|
|
+ end;
|
|
|
+ end;
|
|
|
|
|
|
- { only in case of overflow operations }
|
|
|
- { produce overflow code }
|
|
|
- { we must put it here directly, because sign of operation }
|
|
|
- { is in unsigned VAR!! }
|
|
|
- if mboverflow then
|
|
|
- begin
|
|
|
- if cs_check_overflow in aktlocalswitches then
|
|
|
- begin
|
|
|
- getlabel(hl4);
|
|
|
- if unsigned then
|
|
|
- emitjmp(C_NB,hl4)
|
|
|
+ if not(cs_check_overflow in aktlocalswitches) or
|
|
|
+ not(nodetype in [addn,subn]) then
|
|
|
+ begin
|
|
|
+ case nodetype of
|
|
|
+ ltn,lten,
|
|
|
+ gtn,gten,
|
|
|
+ equaln,unequaln:
|
|
|
+ begin
|
|
|
+ emit_cmp64_hi;
|
|
|
+ firstjmp64bitcmp;
|
|
|
+ emit_cmp64_lo;
|
|
|
+ secondjmp64bitcmp;
|
|
|
+ end;
|
|
|
+ xorn,orn,andn,addn,subn:
|
|
|
+ begin
|
|
|
+ if left.location.loc = LOC_CONSTANT then
|
|
|
+ swapleftright;
|
|
|
+ if (right.location.loc = LOC_CONSTANT) then
|
|
|
+ cg64.a_op64_const_reg_reg(exprasmlist,op,right.location.value,
|
|
|
+ left.location.register64,location.register64)
|
|
|
+ else
|
|
|
+ cg64.a_op64_reg_reg_reg(exprasmlist,op,right.location.register64,
|
|
|
+ left.location.register64,location.register64);
|
|
|
+ end;
|
|
|
else
|
|
|
- emitjmp(C_NO,hl4);
|
|
|
- cg.a_call_name(exprasmlist,'FPC_OVERFLOW');
|
|
|
- cg.a_label(exprasmlist,hl4);
|
|
|
+ internalerror(2002072803);
|
|
|
end;
|
|
|
- end;
|
|
|
-
|
|
|
- { we have LOC_JUMP as result }
|
|
|
- if cmpop then
|
|
|
- location_reset(location,LOC_JUMP,OS_NO)
|
|
|
+ end
|
|
|
else
|
|
|
- location_copy(location,left.location);
|
|
|
+ begin
|
|
|
+ case nodetype of
|
|
|
+ addn:
|
|
|
+ begin
|
|
|
+ op1 := A_ADDC;
|
|
|
+ op2 := A_ADDZEO;
|
|
|
+ end;
|
|
|
+ subn:
|
|
|
+ begin
|
|
|
+ op1 := A_SUBC;
|
|
|
+ op2 := A_SUBFMEO;
|
|
|
+ end;
|
|
|
+ else
|
|
|
+ internalerror(2002072806);
|
|
|
+ end;
|
|
|
+ exprasmlist.concat(taicpu.op_reg_reg_reg(op1,location.registerlow,
|
|
|
+ left.location.registerlow,right.location.registerlow));
|
|
|
+ exprasmlist.concat(taicpu.op_reg_reg_reg(op2,location.registerhigh,
|
|
|
+ right.location.registerhigh,left.location.registerhigh));
|
|
|
+ cg.g_overflowcheck(exprasmlist,self);
|
|
|
+ end;
|
|
|
+
|
|
|
+ clear_left_right(cmpop);
|
|
|
+
|
|
|
end;
|
|
|
-*)
|
|
|
|
|
|
|
|
|
{*****************************************************************************
|
|
@@ -1209,28 +1179,8 @@ interface
|
|
|
else
|
|
|
location_reset(location,LOC_FLAGS,OS_NO);
|
|
|
|
|
|
- load_left_right(cmpop);
|
|
|
-
|
|
|
- // when overflow checking is on, all operands have to be in
|
|
|
- // a register
|
|
|
- if (cs_check_overflow in aktlocalswitches) and
|
|
|
- not cmpop and
|
|
|
- not (nodetype in [orn,andn,xorn]) then
|
|
|
- begin
|
|
|
- { left and right can't be both constants }
|
|
|
- if (left.location.loc = LOC_CONSTANT) then
|
|
|
- begin
|
|
|
- location_force_reg(exprasmlist,left.location,
|
|
|
- def_cgsize(left.resulttype.def),false);
|
|
|
- location.register := left.location.register;
|
|
|
- end
|
|
|
- else if (right.location.loc = LOC_CONSTANT) then
|
|
|
- begin
|
|
|
- location_force_reg(exprasmlist,right.location,
|
|
|
- def_cgsize(right.resulttype.def),false);
|
|
|
- location.register := right.location.register;
|
|
|
- end;
|
|
|
- end;
|
|
|
+ load_left_right(cmpop, (cs_check_overflow in aktlocalswitches) and
|
|
|
+ (nodetype in [addn,subn,muln]));
|
|
|
|
|
|
if (location.register = R_NO) and
|
|
|
not(cmpop) then
|
|
@@ -1321,6 +1271,7 @@ interface
|
|
|
end;
|
|
|
exprasmlist.concat(taicpu.op_reg_reg_reg(op,location.register,
|
|
|
left.location.register,right.location.register));
|
|
|
+ cg.g_overflowcheck(exprasmlist,self);
|
|
|
end;
|
|
|
|
|
|
clear_left_right(cmpop);
|
|
@@ -1331,7 +1282,11 @@ begin
|
|
|
end.
|
|
|
{
|
|
|
$Log$
|
|
|
- Revision 1.2 2002-07-27 20:00:59 jonas
|
|
|
+ Revision 1.3 2002-07-28 16:02:49 jonas
|
|
|
+ + 64 bit operations (badly tested), everything is implemented now!
|
|
|
+ * some small fixes
|
|
|
+
|
|
|
+ Revision 1.2 2002/07/27 20:00:59 jonas
|
|
|
+ second_addboolean(), second_addfloat() and second_addsmallset()
|
|
|
(64bit stuff is all that's left to do)
|
|
|
|