Browse Source

* mod/div for cardinal type fixed

florian 27 years ago
parent
commit
dc329ecee3
2 changed files with 31 additions and 11 deletions
  1. 17 5
      compiler/cg386mat.pas
  2. 14 6
      compiler/pass_1.pas

+ 17 - 5
compiler/cg386mat.pas

@@ -136,9 +136,18 @@ implementation
                         emit_reg_reg(A_MOV,S_L,hreg1,R_EAX);
                      end;
                 end;
-              exprasmlist^.concat(new(pai386,op_none(A_CLTD,S_NO)));
-                 exprasmlist^.concat(new(pai386,op_reg(A_IDIV,S_L,R_EDI)));
-                 if p^.treetype=divn then
+              { sign extension depends on the left type }
+              if porddef(p^.left^.resulttype)^.typ=u32bit then
+                 exprasmlist^.concat(new(pai386,op_reg_reg(A_XOR,S_L,R_EDX,R_EDX)))
+              else
+                 exprasmlist^.concat(new(pai386,op_none(A_CLTD,S_NO)));
+
+              { division depends on the right type }
+              if porddef(p^.right^.resulttype)^.typ=u32bit then
+                exprasmlist^.concat(new(pai386,op_reg(A_DIV,S_L,R_EDI)))
+              else
+                exprasmlist^.concat(new(pai386,op_reg(A_IDIV,S_L,R_EDI)));
+              if p^.treetype=divn then
                 begin
                    { if result register is busy then copy }
                    if popeax then
@@ -156,7 +165,7 @@ implementation
               if popeax then
                 exprasmlist^.concat(new(pai386,op_reg(A_POP,S_L,R_EAX)));
               if popedx then
-                    exprasmlist^.concat(new(pai386,op_reg(A_POP,S_L,R_EDX)));
+                exprasmlist^.concat(new(pai386,op_reg(A_POP,S_L,R_EDX)));
              end;
            { this registers are always used when div/mod are present }
          usedinproc:=usedinproc or ($80 shr byte(R_EAX));
@@ -549,7 +558,10 @@ implementation
 end.
 {
   $Log$
-  Revision 1.5  1998-08-23 16:07:20  florian
+  Revision 1.6  1998-09-09 14:37:37  florian
+    * mod/div for cardinal type fixed
+
+  Revision 1.5  1998/08/23 16:07:20  florian
     * internalerror with mod/div fixed
 
   Revision 1.4  1998/08/18 09:24:38  pierre

+ 14 - 6
compiler/pass_1.pas

@@ -1517,11 +1517,18 @@ unit pass_1;
               p:=t;
               exit;
            end;
-         { !!!!!! u32bit }
-         p^.right:=gentypeconvnode(p^.right,s32bitdef);
-         p^.left:=gentypeconvnode(p^.left,s32bitdef);
+         { the resulttype depends on the right side, because the left becomes }
+         { always 64 bit                                                      }
+         if not(p^.right^.resulttype^.deftype=orddef) or
+           not(porddef(p^.right^.resulttype)^.typ in [s32bit,u32bit]) then
+           p^.right:=gentypeconvnode(p^.right,s32bitdef);
+
+         if not(p^.left^.resulttype^.deftype=orddef) or
+           not(porddef(p^.right^.resulttype)^.typ in [s32bit,u32bit]) then
+           p^.right:=gentypeconvnode(p^.right,s32bitdef);
          firstpass(p^.left);
          firstpass(p^.right);
+         p^.resulttype:=p^.right^.resulttype;
 
          if codegenerror then
            exit;
@@ -1529,8 +1536,6 @@ unit pass_1;
          left_right_max(p);
          if p^.left^.registers32<=p^.right^.registers32 then
            inc(p^.registers32);
-
-         p^.resulttype:=s32bitdef;
          p^.location.loc:=LOC_REGISTER;
       end;
 
@@ -5488,7 +5493,10 @@ unit pass_1;
 end.
 {
   $Log$
-  Revision 1.80  1998-09-08 14:10:11  pierre
+  Revision 1.81  1998-09-09 14:37:39  florian
+    * mod/div for cardinal type fixed
+
+  Revision 1.80  1998/09/08 14:10:11  pierre
     * typen check in read write
       there are probably other inline function that have the same bug !!