From 0473cbf70f8bef27fcbc115733002e412cdda489 Mon Sep 17 00:00:00 2001 From: nickysn Date: Sun, 7 Apr 2013 11:03:08 +0000 Subject: [PATCH] * 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 - --- compiler/nadd.pas | 111 ++++++++++------------------------------------ 1 file changed, 24 insertions(+), 87 deletions(-) diff --git a/compiler/nadd.pas b/compiler/nadd.pas index 1535c3dd80..4c29e5a068 100644 --- a/compiler/nadd.pas +++ b/compiler/nadd.pas @@ -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