* refactored the add node type check pass to handle all native integer sizes with the same common code, without ifdefs

git-svn-id: branches/i8086@24174 -
This commit is contained in:
nickysn 2013-04-07 11:03:08 +00:00
parent 2486009d37
commit 0473cbf70f

View File

@ -1417,22 +1417,27 @@ implementation
if (torddef(rd).ordtype<>u64bit) then
inserttypeconv(right,u64inttype);
end
{ 64 bit cpus do calculations always in 64 bit }
{$ifndef cpu64bitaddr}
{ is there a cardinal? }
else if ((torddef(rd).ordtype=u32bit) or (torddef(ld).ordtype=u32bit)) then
{ is there a larger int? }
else if is_oversizedint(rd) or is_oversizedint(ld) then
begin
{ convert positive constants to u32bit }
if (torddef(ld).ordtype<>u32bit) and
nd:=get_common_intdef(torddef(ld),torddef(rd),false);
inserttypeconv(right,nd);
inserttypeconv(left,nd);
end
{ is there a native unsigned int? }
else if is_nativeuint(rd) or is_nativeuint(ld) then
begin
{ convert positive constants to uinttype }
if (not is_nativeuint(ld)) and
is_constintnode(left) and
(tordconstnode(left).value >= 0) then
inserttypeconv(left,u32inttype);
if (torddef(rd).ordtype<>u32bit) and
inserttypeconv(left,uinttype);
if (not is_nativeuint(rd)) and
is_constintnode(right) and
(tordconstnode(right).value >= 0) then
inserttypeconv(right,u32inttype);
inserttypeconv(right,uinttype);
{ when one of the operand is signed or the operation is subn then perform
the operation in 64bit, can't use rd/ld here because there
the operation in a larger signed type, can't use rd/ld here because there
could be already typeconvs inserted.
This is compatible with the code below for other unsigned types (PFV) }
if is_signed(left.resultdef) or
@ -1442,7 +1447,7 @@ implementation
if nodetype<>subn then
CGMessage(type_h_mixed_signed_unsigned);
{ mark as internal in case added for a subn, so }
{ ttypeconvnode.simplify can remove the 64 bit }
{ ttypeconvnode.simplify can remove the larger }
{ typecast again if semantically correct. Even }
{ if we could detect that here already, we }
{ mustn't do it here because that would change }
@ -1452,80 +1457,19 @@ implementation
not is_signed(right.resultdef)) or
(nodetype in [orn,xorn]) then
include(flags,nf_internal);
inserttypeconv(left,s64inttype);
inserttypeconv(right,s64inttype);
{ get next larger signed int type }
nd:=get_common_intdef(torddef(sinttype),torddef(uinttype),false);
inserttypeconv(left,nd);
inserttypeconv(right,nd);
end
else
begin
if (torddef(left.resultdef).ordtype<>u32bit) then
inserttypeconv(left,u32inttype);
if (torddef(right.resultdef).ordtype<>u32bit) then
inserttypeconv(right,u32inttype);
if not is_nativeuint(left.resultdef) then
inserttypeconv(left,uinttype);
if not is_nativeuint(right.resultdef) then
inserttypeconv(right,uinttype);
end;
end
{$endif cpu64bitaddr}
{ extra int handling for 16-bit and 8-bit cpus }
{$if defined(cpu16bitalu) or defined(cpu8bitalu)}
{ is there a signed 32 bit type ? }
else if ((torddef(rd).ordtype=s32bit) or (torddef(ld).ordtype=s32bit)) then
begin
if (torddef(ld).ordtype<>s32bit) then
inserttypeconv(left,s32inttype);
if (torddef(rd).ordtype<>s32bit) then
inserttypeconv(right,s32inttype);
end
{ is there a unsigned 32 bit type ? }
else if ((torddef(rd).ordtype=u32bit) or (torddef(ld).ordtype=u32bit)) then
begin
if (torddef(ld).ordtype<>u32bit) then
inserttypeconv(left,u32inttype);
if (torddef(rd).ordtype<>u32bit) then
inserttypeconv(right,u32inttype);
end
{ is there a word? }
else if ((torddef(rd).ordtype=u16bit) or (torddef(ld).ordtype=u16bit)) then
begin
{ convert positive constants to u16bit }
if (torddef(ld).ordtype<>u16bit) and
is_constintnode(left) and
(tordconstnode(left).value >= 0) then
inserttypeconv(left,u16inttype);
if (torddef(rd).ordtype<>u16bit) and
is_constintnode(right) and
(tordconstnode(right).value >= 0) then
inserttypeconv(right,u16inttype);
{ When one of the operand is signed then perform
the operation in 32bit, can't use rd/ld here because there
could be already typeconvs inserted.
Note that on 16-bit CPUs subn between 2 unsigned ints isn't
extended to 32-bit. This is Borland Pascal 7 compatible. }
if is_signed(left.resultdef) or
is_signed(right.resultdef) then
begin
{ TODO: add new hint message for mixing 16-bit signed and unsigned ints }
{ CGMessage(type_h_mixed_signed_unsigned);}
{ mark as internal in case added for a or/xor, so }
{ ttypeconvnode.simplify can remove the 32 bit }
{ typecast again if semantically correct. Even }
{ if we could detect that here already, we }
{ mustn't do it here because that would change }
{ overload choosing behaviour etc. The code in }
{ ncnv.pas is run after that is already decided }
if nodetype in [orn,xorn] then
include(flags,nf_internal);
inserttypeconv(left,s32inttype);
inserttypeconv(right,s32inttype);
end
else
begin
if (torddef(left.resultdef).ordtype<>u16bit) then
inserttypeconv(left,u16inttype);
if (torddef(right.resultdef).ordtype<>u16bit) then
inserttypeconv(right,u16inttype);
end;
end
{$endif cpu16bitalu or cpu8bitalu}
{ generic ord conversion is sinttype }
else
begin
@ -1536,15 +1480,8 @@ implementation
is_signed(rd) or
(nodetype=subn) then
begin
{$ifdef cpunodefaultint}
{ for small cpus we use the smallest common type }
nd:=get_common_intdef(torddef(ld),torddef(rd),false);
inserttypeconv(right,nd);
inserttypeconv(left,nd);
{$else cpunodefaultint}
inserttypeconv(right,sinttype);
inserttypeconv(left,sinttype);
{$endif cpunodefaultint}
end
else
begin