Browse Source

* more fixes to the 3-op IMUL spilling:
o Return the correct operation type for all forms of IMUL in
taicpu.spilling_get_operation_type
o Properly support 3-op IMUL in trgx86.do_spill_replace

git-svn-id: trunk@26514 -

nickysn 11 years ago
parent
commit
c83032992d
2 changed files with 51 additions and 8 deletions
  1. 35 3
      compiler/x86/aasmcpu.pas
  2. 16 5
      compiler/x86/rgx86.pas

+ 35 - 3
compiler/x86/aasmcpu.pas

@@ -2992,9 +2992,6 @@ implementation
                 end;
                 end;
               end;
               end;
           end;
           end;
-        { Special cases that can't be decoded from the InsChanges flags }
-        operation_type_table^[A_IMUL,1]:=operand_readwrite;
-        operation_type_table^[A_IMUL,2]:=operand_write;
       end;
       end;
 
 
 
 
@@ -3017,6 +3014,41 @@ implementation
                 internalerror(200506055);
                 internalerror(200506055);
             end
             end
           end
           end
+        { IMUL has 1, 2 and 3-operand forms }
+        else if opcode=A_IMUL then
+          begin
+            case ops of
+              1:
+                if opnr=0 then
+                  result:=operand_read
+                else
+                  internalerror(2014011802);
+              2:
+                begin
+                  case opnr of
+                    0:
+                      result:=operand_read;
+                    1:
+                      result:=operand_readwrite;
+                    else
+                      internalerror(2014011803);
+                  end;
+                end;
+              3:
+                begin
+                  case opnr of
+                    0,1:
+                      result:=operand_read;
+                    2:
+                      result:=operand_write;
+                    else
+                      internalerror(2014011804);
+                  end;
+                end;
+              else
+                internalerror(2014011805);
+            end;
+          end
         else
         else
           result:=operation_type_table^[opcode,opnr];
           result:=operation_type_table^[opcode,opnr];
       end;
       end;

+ 16 - 5
compiler/x86/rgx86.pas

@@ -136,7 +136,7 @@ implementation
                 begin
                 begin
                   { avx instruction?
                   { avx instruction?
                     currently this rule is sufficient but it might be extended }
                     currently this rule is sufficient but it might be extended }
-                  if (ops=3) and (opcode<>A_SHRD) and (opcode<>A_SHLD) then
+                  if (ops=3) and (opcode<>A_SHRD) and (opcode<>A_SHLD) and (opcode<>A_IMUL) then
                     begin
                     begin
                       { avx instructions allow only the first operand (at&t counting) to be a register operand }
                       { avx instructions allow only the first operand (at&t counting) to be a register operand }
                       { all operands must be registers ... }
                       { all operands must be registers ... }
@@ -157,7 +157,7 @@ implementation
                     end
                     end
                   else
                   else
                     begin
                     begin
-                      { We can handle opcodes with 2 and shrd/shld the same way, where the 3rd operand is const or CL,
+                      { We can handle opcodes with 2 and 3-op imul/shrd/shld the same way, where the 3rd operand is const or CL,
                         that doesn't need spilling.
                         that doesn't need spilling.
                         However, due to AT&T order inside the compiler, the 3rd operand is
                         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
                         numbered 0, so look at operand no. 1 and 2 if we have 3 operands by
@@ -274,7 +274,6 @@ implementation
                               A_CVTSS2SI,
                               A_CVTSS2SI,
                               A_CVTTPS2PI,
                               A_CVTTPS2PI,
                               A_CVTTSS2SI,
                               A_CVTTSS2SI,
-                              A_IMUL,
                               A_XORPD,
                               A_XORPD,
                               A_XORPS,
                               A_XORPS,
                               A_ORPD,
                               A_ORPD,
@@ -285,8 +284,11 @@ implementation
                               A_UNPCKHPS,
                               A_UNPCKHPS,
                               A_SHUFPD,
                               A_SHUFPD,
                               A_SHUFPS:
                               A_SHUFPS:
-
                                 replaceoper:=-1;
                                 replaceoper:=-1;
+
+                              A_IMUL:
+                                if ops<>3 then
+                                  replaceoper:=-1;
 {$ifdef x86_64}
 {$ifdef x86_64}
                               A_MOV:
                               A_MOV:
                                  { 64 bit constants can only be moved into registers }
                                  { 64 bit constants can only be moved into registers }
@@ -298,7 +300,16 @@ implementation
 {$endif x86_64}
 {$endif x86_64}
                             end;
                             end;
                           end;
                           end;
-                        end;
+                        2 :
+                          begin
+                            { Some 3-op instructions don't allow memory references
+                              for destination }
+                            case instr.opcode of
+                              A_IMUL:
+                                replaceoper:=-1;
+                            end;
+                          end;
+                      end;
                     end;
                     end;
                 end;
                 end;
              end;
              end;