mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-21 01:29:29 +02:00
* 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:
parent
2486009d37
commit
0473cbf70f
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user