Browse Source

+ enabled the use of the DIV/IDIV instruction for 16-bit div/mod on i8086
* ti8086.moddivnode.pass_generate_code: use cg.a_op_const_reg, instead of
emit_const_reg, in order to support generating plain 8086/8088 code
(shr/shl/sar reg,const is 186+ if const is >= 2).

git-svn-id: trunk@26063 -

nickysn 11 years ago
parent
commit
dc432918da
1 changed files with 28 additions and 7 deletions
  1. 28 7
      compiler/i8086/n8086mat.pas

+ 28 - 7
compiler/i8086/n8086mat.pas

@@ -30,6 +30,8 @@ interface
 
 
     type
     type
       ti8086moddivnode = class(tmoddivnode)
       ti8086moddivnode = class(tmoddivnode)
+         function use_moddiv32bit_helper: boolean;
+         function first_moddivint: tnode; override;
          procedure pass_generate_code;override;
          procedure pass_generate_code;override;
       end;
       end;
 
 
@@ -61,6 +63,25 @@ implementation
                              ti8086moddivnode
                              ti8086moddivnode
 *****************************************************************************}
 *****************************************************************************}
 
 
+
+    function ti8086moddivnode.use_moddiv32bit_helper: boolean;
+      begin
+        result:=is_32bit(left.resultdef) or
+                is_64bit(left.resultdef) or
+                is_32bit(right.resultdef) or
+                is_64bit(right.resultdef);
+      end;
+
+
+    function ti8086moddivnode.first_moddivint: tnode;
+      begin
+        if use_moddiv32bit_helper then
+          result:=inherited first_moddivint
+        else
+          result:=nil;
+      end;
+
+
     function log2(i : word) : word;
     function log2(i : word) : word;
       begin
       begin
         result:=0;
         result:=0;
@@ -116,13 +137,13 @@ implementation
                         hreg2:=cg.getintregister(current_asmdata.CurrAsmList,OS_INT);
                         hreg2:=cg.getintregister(current_asmdata.CurrAsmList,OS_INT);
                         emit_reg_reg(A_MOV,S_W,hreg1,hreg2);
                         emit_reg_reg(A_MOV,S_W,hreg1,hreg2);
                         {If the left value is signed, hreg2=$ffff, otherwise 0.}
                         {If the left value is signed, hreg2=$ffff, otherwise 0.}
-                        emit_const_reg(A_SAR,S_W,15,hreg2);
+                        cg.a_op_const_reg(current_asmdata.CurrAsmList,OP_SAR,OS_16,15,hreg2);
                         {If signed, hreg2=right value-1, otherwise 0.}
                         {If signed, hreg2=right value-1, otherwise 0.}
                         emit_const_reg(A_AND,S_W,tordconstnode(right).value.svalue-1,hreg2);
                         emit_const_reg(A_AND,S_W,tordconstnode(right).value.svalue-1,hreg2);
                         { add to the left value }
                         { add to the left value }
                         emit_reg_reg(A_ADD,S_W,hreg2,hreg1);
                         emit_reg_reg(A_ADD,S_W,hreg2,hreg1);
                         { do the shift }
                         { do the shift }
-                        emit_const_reg(A_SAR,S_W,power,hreg1);
+                        cg.a_op_const_reg(current_asmdata.CurrAsmList,OP_SAR,OS_16,power,hreg1);
                       end
                       end
                     else
                     else
                       begin
                       begin
@@ -135,11 +156,11 @@ implementation
                         else
                         else
                           emit_const_reg(A_ADD,S_W,tordconstnode(right).value.svalue-1,hreg1);
                           emit_const_reg(A_ADD,S_W,tordconstnode(right).value.svalue-1,hreg1);
                         cg.a_label(current_asmdata.CurrAsmList,hl);
                         cg.a_label(current_asmdata.CurrAsmList,hl);
-                        emit_const_reg(A_SAR,S_W,power,hreg1);
+                        cg.a_op_const_reg(current_asmdata.CurrAsmList,OP_SAR,OS_16,power,hreg1);
                       end
                       end
                   end
                   end
                 else
                 else
-                  emit_const_reg(A_SHR,S_W,power,hreg1);
+                  cg.a_op_const_reg(current_asmdata.CurrAsmList,OP_SHR,OS_16,power,hreg1);
                 location.register:=hreg1;
                 location.register:=hreg1;
               end
               end
             else
             else
@@ -208,8 +229,8 @@ implementation
                         printf ("; quotient now in DX\n");
                         printf ("; quotient now in DX\n");
                       }
                       }
                     if s<>0 then
                     if s<>0 then
-                      emit_const_reg(A_SAR,S_W,s,NR_DX);
-                    emit_const_reg(A_SHR,S_W,15,NR_AX);
+                      cg.a_op_const_reg(current_asmdata.CurrAsmList,OP_SAR,OS_16,s,NR_DX);
+                    cg.a_op_const_reg(current_asmdata.CurrAsmList,OP_SHR,OS_16,15,NR_AX);
                     emit_reg_reg(A_ADD,S_W,NR_AX,NR_DX);
                     emit_reg_reg(A_ADD,S_W,NR_AX,NR_DX);
                     if e<0 then
                     if e<0 then
                       emit_reg(A_NEG,S_W,NR_DX);
                       emit_reg(A_NEG,S_W,NR_DX);
@@ -304,7 +325,7 @@ implementation
                             emit_const_reg(A_ADC,S_W,0,NR_DX);
                             emit_const_reg(A_ADC,S_W,0,NR_DX);
                           end;
                           end;
                         if s<>0 then
                         if s<>0 then
-                          emit_const_reg(A_SHR,S_W,aint(s),NR_DX);
+                          cg.a_op_const_reg(current_asmdata.CurrAsmList,OP_SHR,OS_16,aint(s),NR_DX);
                         cg.ungetcpuregister(current_asmdata.CurrAsmList,NR_DX);
                         cg.ungetcpuregister(current_asmdata.CurrAsmList,NR_DX);
                         cg.ungetcpuregister(current_asmdata.CurrAsmList,NR_AX);
                         cg.ungetcpuregister(current_asmdata.CurrAsmList,NR_AX);
                         location.register:=cg.getintregister(current_asmdata.CurrAsmList,OS_INT);
                         location.register:=cg.getintregister(current_asmdata.CurrAsmList,OS_INT);