summaryrefslogtreecommitdiff
path: root/avx512-0037785/compiler/nflw.pas
diff options
context:
space:
mode:
Diffstat (limited to 'avx512-0037785/compiler/nflw.pas')
-rw-r--r--avx512-0037785/compiler/nflw.pas131
1 files changed, 128 insertions, 3 deletions
diff --git a/avx512-0037785/compiler/nflw.pas b/avx512-0037785/compiler/nflw.pas
index 210de18b5f..527484385a 100644
--- a/avx512-0037785/compiler/nflw.pas
+++ b/avx512-0037785/compiler/nflw.pas
@@ -302,6 +302,9 @@ implementation
{$ifdef i8086}
cpuinfo,
{$endif i8086}
+ {$if defined(xtensa) or defined(i386)}
+ cpuinfo,
+ {$endif defined(xtensa) or defined(i386)}
cgbase,procinfo
;
@@ -985,9 +988,14 @@ implementation
typecheckpass(expr);
end;
case expr.resultdef.typ of
- stringdef: result:=create_string_for_in_loop(hloopvar, hloopbody, expr);
- arraydef: result:=create_array_for_in_loop(hloopvar, hloopbody, expr);
- setdef: result:=create_set_for_in_loop(hloopvar, hloopbody, expr);
+ stringdef:
+ result:=create_string_for_in_loop(hloopvar, hloopbody, expr);
+ arraydef:
+ result:=create_array_for_in_loop(hloopvar, hloopbody, expr);
+ setdef:
+ result:=create_set_for_in_loop(hloopvar, hloopbody, expr);
+ undefineddef:
+ result:=cnothingnode.create;
else
begin
result:=cerrornode.create;
@@ -1549,8 +1557,14 @@ implementation
function tifnode.internalsimplify(warn: boolean) : tnode;
+ var
+ thenstmnt, elsestmnt: tnode;
+ in_nr: tinlinenumber;
+ paratype: tdef;
begin
result:=nil;
+ elsestmnt:=nil;
+ in_nr:=Default(tinlinenumber);
{ optimize constant expressions }
if (left.nodetype=ordconstn) then
begin
@@ -1575,6 +1589,117 @@ implementation
CGMessagePos(right.fileinfo,cg_w_unreachable_code);
end;
end;
+{$ifndef llvm}
+{$if defined(i386) or defined(x86_64) or defined(xtensa)}
+ { use min/max intrinsic?
+ convert (with <op> being <, >, >=, <=
+ if a <op> b then
+ x:=a
+ else
+ x:=b;
+
+ and
+
+ if a <op> b then
+ x:=a;
+
+ into appropriate min/max intrinsics
+
+ }
+ if (cs_opt_level2 in current_settings.optimizerswitches) and
+ (left.nodetype in [gtn,gten,ltn,lten]) and IsSingleStatement(right,thenstmnt) and
+ ((t1=nil) or IsSingleStatement(t1,elsestmnt)) and
+ (thenstmnt.nodetype=assignn) and ((t1=nil) or (elsestmnt.nodetype=assignn)) and
+ not(might_have_sideeffects(left)) and
+ ((t1=nil) or tassignmentnode(thenstmnt).left.isequal(tassignmentnode(elsestmnt).left)) and
+{$if defined(i386) or defined(x86_64)}
+{$ifdef i386}
+ (((current_settings.fputype>=fpu_sse) and is_single(tassignmentnode(thenstmnt).left.resultdef)) or
+ ((current_settings.fputype>=fpu_sse2) and is_double(tassignmentnode(thenstmnt).left.resultdef))
+ ) and
+{$else i386}
+ (is_single(tassignmentnode(thenstmnt).left.resultdef) or is_double(tassignmentnode(thenstmnt).left.resultdef)) and
+{$endif i386}
+{$endif defined(i386) or defined(x86_64)}
+{$if defined(xtensa)}
+ (CPUXTENSA_HAS_MINMAX in cpu_capabilities[current_settings.cputype]) and is_32bitint(tassignmentnode(thenstmnt).right.resultdef) and
+{$endif defined(xtensa)}
+ (
+ { the right size of the assignment in the then clause must either }
+
+ { equal to the left ... }
+ (tassignmentnode(thenstmnt).right.isequal(taddnode(left).left) and
+
+ { ... and the else clause must be either not exist }
+ { and the left side of the assignment in the then clause must be }
+ { equal to the right operand of the comparison operator }
+ (
+ ((t1=nil) and (tassignmentnode(thenstmnt).left.isequal(taddnode(left).right))) or
+
+ { or the else clause exists and the right side of the assignment in the else clause }
+ { must be equal to the right side of the comparison operator }
+ (assigned(elsestmnt) and tassignmentnode(elsestmnt).right.isequal(taddnode(left).right)))
+ ) or
+ { ... or right operand of the comparison operator }
+
+ (tassignmentnode(thenstmnt).right.isequal(taddnode(left).right) and
+ { ... and the else clause must be either not exist }
+ { and the left side of the assignment in the then clause must be }
+ { equal to the left operand of the comparison operator }
+ (
+ ((t1=nil) and (tassignmentnode(thenstmnt).left.isequal(taddnode(left).left))) or
+
+ { or the else clause exists and the right side of the assignment in the else clause }
+ { must be equal to the left side of the comparison operator }
+ (assigned(elsestmnt) and tassignmentnode(elsestmnt).right.isequal(taddnode(left).left))
+ )
+ )
+ ) then
+ begin
+ paratype:=tassignmentnode(thenstmnt).left.resultdef;
+ if ((left.nodetype in [gtn,gten]) and
+ tassignmentnode(thenstmnt).right.isequal(taddnode(left).left)) or
+ ((left.nodetype in [ltn,lten]) and
+ tassignmentnode(thenstmnt).right.isequal(taddnode(left).right)) then
+ begin
+ if is_double(paratype) then
+ in_nr:=in_max_double
+ else if is_single(paratype) then
+ in_nr:=in_max_single
+ else if is_u32bitint(paratype) then
+ in_nr:=in_max_dword
+ else if is_s32bitint(paratype) then
+ in_nr:=in_max_longint;
+ end
+ else
+ begin
+ if is_double(paratype) then
+ in_nr:=in_min_double
+ else if is_single(paratype) then
+ in_nr:=in_min_single
+ else if is_u32bitint(paratype) then
+ in_nr:=in_min_dword
+ else if is_s32bitint(paratype) then
+ in_nr:=in_min_longint;
+ end;
+ { for inline nodes, the first parameter is the last one in the linked list
+
+ Due to the defined behaviour for the min/max intrinsics that in case of a NaN
+ the second parameter is taken, we have to put the else part into the second parameter
+ thus pass it to the first callparanode call }
+ if t1=nil then
+ Result:=cassignmentnode.create_internal(tassignmentnode(thenstmnt).left.getcopy,
+ cinlinenode.create(in_nr,false,ccallparanode.create(tassignmentnode(thenstmnt).left.getcopy,
+ ccallparanode.create(tassignmentnode(thenstmnt).right.getcopy,nil)))
+ )
+ else
+ Result:=cassignmentnode.create_internal(tassignmentnode(thenstmnt).left.getcopy,
+ cinlinenode.create(in_nr,false,ccallparanode.create(tassignmentnode(elsestmnt).right.getcopy,
+ ccallparanode.create(tassignmentnode(thenstmnt).right.getcopy,nil)))
+ );
+ end;
+{$endif defined(i386) or defined(x86_64) or defined(xtensa)}
+{$endif llvm}
end;