* extract calculation of a NOT value to a separate function

git-svn-id: trunk@45050 -
This commit is contained in:
svenbarth 2020-04-24 14:08:58 +00:00
parent c7c4f0bf39
commit 89434f0124
2 changed files with 59 additions and 46 deletions

View File

@ -349,6 +349,10 @@ interface
signdness, the result will also get that signdness }
function get_common_intdef(ld, rd: torddef; keep_sign_if_equal: boolean): torddef;
{ # calculates "not v" based on the provided def; returns true if the def
was negatable, false otherwise }
function calc_not_ordvalue(var v:Tconstexprint; var def:tdef):boolean;
{ # returns whether the type is potentially a valid type of/for an "univ" parameter
(basically: it must have a compile-time size) }
function is_valid_univ_para_type(def: tdef): boolean;
@ -1747,6 +1751,59 @@ implementation
end;
function calc_not_ordvalue(var v:Tconstexprint;var def:tdef):boolean;
begin
if not assigned(def) or (def.typ<>orddef) then
exit(false);
result:=true;
case torddef(def).ordtype of
pasbool1,
pasbool8,
pasbool16,
pasbool32,
pasbool64:
v:=byte(not(boolean(int64(v))));
bool8bit,
bool16bit,
bool32bit,
bool64bit:
begin
if v=0 then
v:=-1
else
v:=0;
end;
uchar,
uwidechar,
u8bit,
s8bit,
u16bit,
s16bit,
s32bit,
u32bit,
s64bit,
u64bit:
begin
{ unsigned, equal or bigger than the native int size? }
if (torddef(def).ordtype in [u64bit,u32bit,u16bit,u8bit,uchar,uwidechar]) and
(is_nativeord(def) or is_oversizedord(def)) then
begin
{ Delphi-compatible: not dword = dword (not word = longint) }
{ Extension: not qword = qword }
v:=qword(not qword(v));
{ will be truncated by the ordconstnode for u32bit }
end
else
begin
v:=int64(not int64(v));
def:=get_common_intdef(torddef(def),torddef(sinttype),false);
end;
end;
else
result:=false;
end;
end;
function is_valid_univ_para_type(def: tdef): boolean;
begin
result:=

View File

@ -1176,52 +1176,8 @@ implementation
begin
v:=tordconstnode(left).value;
def:=left.resultdef;
case torddef(left.resultdef).ordtype of
pasbool1,
pasbool8,
pasbool16,
pasbool32,
pasbool64:
v:=byte(not(boolean(int64(v))));
bool8bit,
bool16bit,
bool32bit,
bool64bit:
begin
if v=0 then
v:=-1
else
v:=0;
end;
uchar,
uwidechar,
u8bit,
s8bit,
u16bit,
s16bit,
s32bit,
u32bit,
s64bit,
u64bit:
begin
{ unsigned, equal or bigger than the native int size? }
if (torddef(left.resultdef).ordtype in [u64bit,u32bit,u16bit,u8bit,uchar,uwidechar]) and
(is_nativeord(left.resultdef) or is_oversizedord(left.resultdef)) then
begin
{ Delphi-compatible: not dword = dword (not word = longint) }
{ Extension: not qword = qword }
v:=qword(not qword(v));
{ will be truncated by the ordconstnode for u32bit }
end
else
begin
v:=int64(not int64(v));
def:=get_common_intdef(torddef(left.resultdef),torddef(sinttype),false);
end;
end;
else
CGMessage(type_e_mismatch);
end;
if not calc_not_ordvalue(v,def) then
CGMessage(type_e_mismatch);
{ not-nodes are not range checked by the code generator -> also
don't range check while inlining; the resultdef is a bit tricky
though: the node's resultdef gets changed in most cases compared