Sfoglia il codice sorgente

* always use IMUL instead of MUL on i386, when doing a 32->32 multiplication
without overflow checking

git-svn-id: trunk@26498 -

nickysn 11 anni fa
parent
commit
5d75bf4f92
2 ha cambiato i file con 15 aggiunte e 0 eliminazioni
  1. 5 0
      compiler/i386/n386add.pas
  2. 10 0
      compiler/x86/cgx86.pas

+ 5 - 0
compiler/i386/n386add.pas

@@ -68,6 +68,11 @@ interface
     begin
     begin
       unsigned:=not(is_signed(left.resultdef)) or
       unsigned:=not(is_signed(left.resultdef)) or
                 not(is_signed(right.resultdef));
                 not(is_signed(right.resultdef));
+      { use IMUL instead of MUL in case overflow checking is off and we're
+        doing a 32->32-bit multiplication }
+      if not (cs_check_overflow in current_settings.localswitches) and
+         not is_64bit(resultdef) then
+        unsigned:=false;
       if (nodetype=muln) and (unsigned or is_64bit(resultdef)) then
       if (nodetype=muln) and (unsigned or is_64bit(resultdef)) then
         second_mul(unsigned)
         second_mul(unsigned)
       else
       else

+ 10 - 0
compiler/x86/cgx86.pas

@@ -1697,6 +1697,8 @@ unit cgx86;
             end;
             end;
           OP_MUL,OP_IMUL:
           OP_MUL,OP_IMUL:
             begin
             begin
+              if not (cs_check_overflow in current_settings.localswitches) then
+                op:=OP_IMUL;
               if op = OP_IMUL then
               if op = OP_IMUL then
                 list.concat(taicpu.op_const_reg(A_IMUL,TCgSize2OpSize[size],a,reg))
                 list.concat(taicpu.op_const_reg(A_IMUL,TCgSize2OpSize[size],a,reg))
               else
               else
@@ -1825,6 +1827,8 @@ unit cgx86;
             End;
             End;
           OP_MUL,OP_IMUL:
           OP_MUL,OP_IMUL:
             begin
             begin
+              if not (cs_check_overflow in current_settings.localswitches) then
+                op:=OP_IMUL;
               { can't multiply a memory location directly with a constant }
               { can't multiply a memory location directly with a constant }
               if op = OP_IMUL then
               if op = OP_IMUL then
                 inherited a_op_const_ref(list,op,size,a,tmpref)
                 inherited a_op_const_ref(list,op,size,a,tmpref)
@@ -1915,6 +1919,8 @@ unit cgx86;
         check_register_size(size,src);
         check_register_size(size,src);
         check_register_size(size,dst);
         check_register_size(size,dst);
         dstsize := tcgsize2opsize[size];
         dstsize := tcgsize2opsize[size];
+        if (op=OP_MUL) and not (cs_check_overflow in current_settings.localswitches) then
+          op:=OP_IMUL;
         case op of
         case op of
           OP_NEG,OP_NOT:
           OP_NEG,OP_NOT:
             begin
             begin
@@ -1952,6 +1958,8 @@ unit cgx86;
         tmpref:=ref;
         tmpref:=ref;
         make_simple_ref(list,tmpref);
         make_simple_ref(list,tmpref);
         check_register_size(size,reg);
         check_register_size(size,reg);
+        if (op=OP_MUL) and not (cs_check_overflow in current_settings.localswitches) then
+          op:=OP_IMUL;
         case op of
         case op of
           OP_NEG,OP_NOT,OP_IMUL:
           OP_NEG,OP_NOT,OP_IMUL:
             begin
             begin
@@ -1977,6 +1985,8 @@ unit cgx86;
         tmpref:=ref;
         tmpref:=ref;
         make_simple_ref(list,tmpref);
         make_simple_ref(list,tmpref);
         check_register_size(size,reg);
         check_register_size(size,reg);
+        if (op=OP_MUL) and not (cs_check_overflow in current_settings.localswitches) then
+          op:=OP_IMUL;
         case op of
         case op of
           OP_NEG,OP_NOT:
           OP_NEG,OP_NOT:
             begin
             begin