diff --git a/compiler/x86/rgx86.pas b/compiler/x86/rgx86.pas index 49b9b2f944..cc91fdba3c 100644 --- a/compiler/x86/rgx86.pas +++ b/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;