Ver código fonte

Merged revisions 6959,6974,6976,6996-6997,7002,7007,7016,7020-7021,7033,7037,7040,7042,7045,7068-7069,7075-7079,7087,7094,7098-7099,7101,7103,7109,7115-7119,7128,7136-7137,7139,7150,7160-7162,7175,7179,7183,7190-7195,7198,7202,7205-7206,7208-7217,7220-7222,7225-7228,7230,7233,7239-7241,7244,7246,7252 via svnmerge from
http://svn.freepascal.org/svn/fpc/trunk

........
r6959 | jonas | 2007-03-23 01:21:46 +0100 (Fri, 23 Mar 2007) | 2 lines

* fixed SSE2 substraction when both operands are on the 80x87 fpu stack
........
r7183 | daniel | 2007-04-28 21:11:17 +0200 (Sat, 28 Apr 2007) | 2 lines

+ Allow replace spilling for "opcode register,const" and "opcode const,register"
........
r7252 | daniel | 2007-05-03 22:56:09 +0200 (Thu, 03 May 2007) | 2 lines

* Fix replace spilling of shld/shrd.
........

git-svn-id: branches/fixes_2_2@8543 -

peter 18 anos atrás
pai
commit
6fdeb2035a
1 arquivos alterados com 104 adições e 75 exclusões
  1. 104 75
      compiler/x86/rgx86.pas

+ 104 - 75
compiler/x86/rgx86.pas

@@ -111,8 +111,13 @@ implementation
 
 
     function trgx86.do_spill_replace(list:TAsmList;instr:taicpu;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.}
+
       var
-        replaceoper : longint;
+        n,replaceoper : longint;
       begin
         result:=false;
         with instr do
@@ -129,86 +134,110 @@ implementation
                     end;
                 end;
               2,3 :
-                begin
+                begin 
                   { We can handle opcodes with 2 and 3 operands the same way. The opcodes
                     with 3 registers are shrd/shld, where the 3rd operand is const or CL,
-                    that doesn't need spilling }
-                  if (oper[0]^.typ=top_reg) and
-                     (oper[1]^.typ=top_reg) and
-                     (get_alias(getsupreg(oper[0]^.reg))<>get_alias(getsupreg(oper[1]^.reg))) then
+                    that doesn't need spilling.
+                    However, due to AT&T order inside the compiler, the 3rd operand is
+                    numbered 0, so look at operand no. 1 and 2 if we have 3 operands by
+                    adding a "n". }
+                  n:=0;
+                  if ops=3 then
+                    n:=1;
+                  if (oper[n+0]^.typ=top_reg) and
+                     (oper[n+1]^.typ=top_reg) and
+                     (get_alias(getsupreg(oper[n+0]^.reg))<>get_alias(getsupreg(oper[n+1]^.reg))) then
                     begin
                       { One of the arguments shall be able to be replaced }
-                      if (getregtype(oper[0]^.reg)=regtype) and
-                         (get_alias(getsupreg(oper[0]^.reg))=orgreg) then
-                        replaceoper:=0
+                      if (getregtype(oper[n+0]^.reg)=regtype) and
+                         (get_alias(getsupreg(oper[n+0]^.reg))=orgreg) then
+                        replaceoper:=0+n
                       else
-                        if (getregtype(oper[1]^.reg)=regtype) and
-                           (get_alias(getsupreg(oper[1]^.reg))=orgreg) then
-                          replaceoper:=1
+                        if (getregtype(oper[n+1]^.reg)=regtype) and
+                           (get_alias(getsupreg(oper[n+1]^.reg))=orgreg) then
+                          replaceoper:=1+n
+                      else
+                        internalerror(200704281);
+                    end;
+                  if (oper[n+0]^.typ=top_reg) and
+                     (oper[n+1]^.typ=top_const) then
+                    begin
+                      if (getregtype(oper[0+n]^.reg)=regtype) and
+                         (get_alias(getsupreg(oper[0+n]^.reg))=orgreg) then
+                        replaceoper:=0+n
                       else
-                        internalerror(200410106);
-                      case replaceoper of
-                        0 :
-                          begin
-                            { Some instructions don't allow memory references
-                              for source }
-                            case instr.opcode of
-                              A_BT,
-                              A_BTS,
-                              A_BTC,
-                              A_BTR :
-                                replaceoper:=-1;
-                            end;
-                          end;
-                        1 :
-                          begin
-                            { Some instructions don't allow memory references
-                              for destination }
-                            case instr.opcode of
-                              A_MOVZX,
-                              A_MOVSX,
-                              A_MULSS,
-                              A_MULSD,
-                              A_SUBSS,
-                              A_SUBSD,
-                              A_ADDSD,
-                              A_ADDSS,
-                              A_DIVSD,
-                              A_DIVSS,
-                              A_SHLD,
-                              A_SHRD,
-                              A_CVTDQ2PD,
-                              A_CVTDQ2PS,
-                              A_CVTPD2DQ,
-                              A_CVTPD2PI,
-                              A_CVTPD2PS,
-                              A_CVTPI2PD,
-                              A_CVTPS2DQ,
-                              A_CVTPS2PD,
-                              A_CVTSD2SI,
-                              A_CVTSD2SS,
-                              A_CVTSI2SD,
-                              A_CVTSS2SD,
-                              A_CVTTPD2PI,
-                              A_CVTTPD2DQ,
-                              A_CVTTPS2DQ,
-                              A_CVTTSD2SI,
-                              A_CVTPI2PS,
-                              A_CVTPS2PI,
-                              A_CVTSI2SS,
-                              A_CVTSS2SI,
-                              A_CVTTPS2PI,
-                              A_CVTTSS2SI,
-                              A_IMUL,
-                              A_XORPD,
-                              A_XORPS,
-                              A_ORPD,
-                              A_ORPS,
-                              A_ANDPD,
-                              A_ANDPS:
-                                replaceoper:=-1;
-                            end;
-                          end;
+                        internalerror(200704282);
+                    end;
+                  if (oper[n+0]^.typ=top_const) and
+                     (oper[n+1]^.typ=top_reg) then
+                    begin
+                      if (getregtype(oper[1+n]^.reg)=regtype) and
+                         (get_alias(getsupreg(oper[1+n]^.reg))=orgreg) then
+                        replaceoper:=1+n
+                      else
+                        internalerror(200704283);
+                    end;
+                  case replaceoper of
+                    0 :
+                      begin
+                        { Some instructions don't allow memory references
+                          for source }
+                        case instr.opcode of
+                          A_BT,
+                          A_BTS,
+                          A_BTC,
+                          A_BTR :
+                            replaceoper:=-1;
+                        end;
+                      end;
+                    1 :
+                      begin
+                        { Some instructions don't allow memory references
+                          for destination }
+                        case instr.opcode of
+                          A_MOVZX,
+                          A_MOVSX,
+                          A_MULSS,
+                          A_MULSD,
+                          A_SUBSS,
+                          A_SUBSD,
+                          A_ADDSD,
+                          A_ADDSS,
+                          A_DIVSD,
+                          A_DIVSS,
+                          A_SHLD,
+                          A_SHRD,
+                          A_CVTDQ2PD,
+                          A_CVTDQ2PS,
+                          A_CVTPD2DQ,
+                          A_CVTPD2PI,
+                          A_CVTPD2PS,
+                          A_CVTPI2PD,
+                          A_CVTPS2DQ,
+                          A_CVTPS2PD,
+                          A_CVTSD2SI,
+                          A_CVTSD2SS,
+                          A_CVTSI2SD,
+                          A_CVTSS2SD,
+                          A_CVTTPD2PI,
+                          A_CVTTPD2DQ,
+                          A_CVTTPS2DQ,
+                          A_CVTTSD2SI,
+                          A_CVTPI2PS,
+                          A_CVTPS2PI,
+                          A_CVTSI2SS,
+                          A_CVTSS2SI,
+                          A_CVTTPS2PI,
+                          A_CVTTSS2SI,
+                          A_IMUL,
+                          A_XORPD,
+                          A_XORPS,
+                          A_ORPD,
+                          A_ORPS,
+                          A_ANDPD,
+                          A_ANDPS:
+                            replaceoper:=-1;
+                        end;
                       end;
                     end;
                 end;