Ver código fonte

* avoid spilling of 2nd and 3rd operand of avx instructions

git-svn-id: trunk@33877 -
florian 9 anos atrás
pai
commit
180e0e7561
1 arquivos alterados com 54 adições e 3 exclusões
  1. 54 3
      compiler/x86/rgx86.pas

+ 54 - 3
compiler/x86/rgx86.pas

@@ -107,11 +107,56 @@ implementation
       end;
 
 
+    { Decide wether a "replace" spill is possible, i.e. wether we can replace a register
+      in an instruction by a memory reference. For example, in "mov ireg26d,0", the imaginary
+      register ireg26d can be replaced by a memory reference.}
     function trgx86.do_spill_replace(list:TAsmList;instr:tai_cpu_abstract_sym;orgreg:tsuperregister;const spilltemp:treference):boolean;
 
-    {Decide wether a "replace" spill is possible, i.e. wether we can replace a register
-     in an instruction by a memory reference. For example, in "mov ireg26d,0", the imaginary
-     register ireg26d can be replaced by a memory reference.}
+       { returns true if opcde is an avx opcode which allows only the first (zero) operand might be a memory reference }
+       function avx_opcode_only_op0_may_be_memref(opcode : TAsmOp) : boolean;
+         begin
+           case opcode of
+             A_VMULSS,
+             A_VMULSD,
+             A_VSUBSS,
+             A_VSUBSD,
+             A_VADDSD,
+             A_VADDSS,
+             A_VDIVSD,
+             A_VDIVSS,
+             A_VSQRTSD,
+             A_VSQRTSS,
+             A_VCVTDQ2PD,
+             A_VCVTDQ2PS,
+             A_VCVTPD2DQ,
+             A_VCVTPD2PS,
+             A_VCVTPS2DQ,
+             A_VCVTPS2PD,
+             A_VCVTSD2SI,
+             A_VCVTSD2SS,
+             A_VCVTSI2SD,
+             A_VCVTSS2SD,
+             A_VCVTTPD2DQ,
+             A_VCVTTPS2DQ,
+             A_VCVTTSD2SI,
+             A_VCVTSI2SS,
+             A_VCVTSS2SI,
+             A_VCVTTSS2SI,
+             A_VXORPD,
+             A_VXORPS,
+             A_VORPD,
+             A_VORPS,
+             A_VANDPD,
+             A_VANDPS,
+             A_VUNPCKLPS,
+             A_VUNPCKHPS,
+             A_VSHUFPD:
+               result:=true;
+             else
+               result:=false;
+           end;
+         end;
+
 
       var
         n,replaceoper : longint;
@@ -309,6 +354,9 @@ implementation
                                      (oper[0]^.val>high(longint))) then
                                    replaceoper:=-1;
 {$endif x86_64}
+                              else
+                                if avx_opcode_only_op0_may_be_memref(opcode) then
+                                  replaceoper:=-1;
                             end;
                           end;
                         2 :
@@ -318,6 +366,9 @@ implementation
                             case instr.opcode of
                               A_IMUL:
                                 replaceoper:=-1;
+                              else
+                                if avx_opcode_only_op0_may_be_memref(opcode) then
+                                  replaceoper:=-1;
                             end;
                           end;
                       end;