Browse Source

+ some basic operations with qwords and int64 added: +, xor, and, or;
the register allocation works fine

florian 27 years ago
parent
commit
86b17cd44f
1 changed files with 76 additions and 81 deletions
  1. 76 81
      compiler/cg386add.pas

+ 76 - 81
compiler/cg386add.pas

@@ -459,15 +459,16 @@ implementation
       label do_normal;
 
       var
-         hregister : tregister;
+         hregister,hregister2 : tregister;
          noswap,popeax,popedx,
          pushed,mboverflow,cmpop : boolean;
-         op : tasmop;
+         op,op2 : tasmop;
          flags : tresflags;
          otl,ofl : plabel;
          power : longint;
          opsize : topsize;
          hl4: plabel;
+         hr : preference;
 
          { true, if unsigned types are compared }
          unsigned : boolean;
@@ -1088,6 +1089,7 @@ implementation
                       addn : begin
                                 begin
                                   op:=A_ADD;
+                                  op2:=A_ADC;
                                   mboverflow:=true;
                                 end;
                              end;
@@ -1102,17 +1104,35 @@ implementation
                              end;
                       subn : begin
                                 op:=A_SUB;
+                                op2:=A_SBB;
                                 mboverflow:=true;
                              end;
-                  ltn,lten,
-                  gtn,gten,
-           equaln,unequaln : begin
+                      ltn,lten,
+                      gtn,gten,
+                      equaln,unequaln:
+                             begin
                                op:=A_CMP;
-                               cmpop:=true;
+                               op2:=A_CMP;
+                               { cmpop is set later, if necessary }
                              end;
-                      xorn : op:=A_XOR;
-                       orn : op:=A_OR;
-                      andn : op:=A_AND;
+
+                      xorn:
+                        begin
+                           op:=A_XOR;
+                           op2:=A_XOR;
+                        end;
+
+                      orn:
+                        begin
+                           op:=A_OR;
+                           op2:=A_OR;
+                        end;
+
+                      andn:
+                        begin
+                           op:=A_AND;
+                           op2:=A_AND;
+                        end;
                    else
                      CGMessage(type_e_mismatch);
                    end;
@@ -1129,24 +1149,28 @@ implementation
                              { it is OK if this is the destination }
                              if is_in_dest then
                                begin
-                                  hregister:=p^.location.register;
-                                  emit_reg_reg(A_MOV,opsize,p^.left^.location.register,
+                                  hregister:=p^.location.registerlow;
+                                  hregister2:=p^.location.registerhigh;
+                                  emit_reg_reg(A_MOV,opsize,p^.left^.location.registerlow,
                                     hregister);
+                                  emit_reg_reg(A_MOV,opsize,p^.left^.location.registerlow,
+                                    hregister2);
                                end
                              else
                              if cmpop then
                                begin
                                   { do not disturb the register }
-                                  hregister:=p^.location.register;
+                                  hregister:=p^.location.registerlow;
+                                  hregister2:=p^.location.registerhigh;
                                end
                              else
                                begin
-                                  case opsize of
-                                     S_L : hregister:=getregister32;
-                                     S_B : hregister:=reg32toreg8(getregister32);
-                                  end;
-                                  emit_reg_reg(A_MOV,opsize,p^.left^.location.register,
+                                  hregister:=getregister32;
+                                  hregister2:=getregister32;
+                                  emit_reg_reg(A_MOV,opsize,p^.left^.location.registerlow,
                                     hregister);
+                                  emit_reg_reg(A_MOV,opsize,p^.left^.location.registerhigh,
+                                    hregister2);
                                end
                           end
                         else
@@ -1155,25 +1179,31 @@ implementation
                              del_reference(p^.left^.location.reference);
                              if is_in_dest then
                                begin
-                                  hregister:=p^.location.register;
+                                  hregister:=p^.location.registerlow;
+                                  hregister2:=p^.location.registerhigh;
                                   exprasmlist^.concat(new(pai386,op_ref_reg(A_MOV,opsize,
-                                  newreference(p^.left^.location.reference),hregister)));
+                                    newreference(p^.left^.location.reference),hregister)));
+                                  hr:=newreference(p^.left^.location.reference);
+                                  inc(hr^.offset,4);
+                                  exprasmlist^.concat(new(pai386,op_ref_reg(A_MOV,opsize,
+                                    hr,hregister2)));
                                end
                              else
                                begin
-                                  { first give free, then demand new register }
-                                  case opsize of
-                                     S_L : hregister:=getregister32;
-                                     S_W : hregister:=reg32toreg16(getregister32);
-                                     S_B : hregister:=reg32toreg8(getregister32);
-                                  end;
+                                  hregister:=getregister32;
+                                  hregister2:=getregister32;
                                   exprasmlist^.concat(new(pai386,op_ref_reg(A_MOV,opsize,
                                     newreference(p^.left^.location.reference),hregister)));
+                                  hr:=newreference(p^.left^.location.reference);
+                                  inc(hr^.offset,4);
+                                  exprasmlist^.concat(new(pai386,op_ref_reg(A_MOV,opsize,
+                                    newreference(p^.left^.location.reference),hregister2)));
                                end;
                           end;
                         clear_location(p^.location);
                         p^.location.loc:=LOC_REGISTER;
-                        p^.location.register:=hregister;
+                        p^.location.registerlow:=hregister;
+                        p^.location.registerhigh:=hregister2;
                      end
                    else
                      { if on the right the register then swap }
@@ -1194,18 +1224,12 @@ implementation
                           begin
                              if p^.right^.location.loc=LOC_CREGISTER then
                                begin
-                                  if extra_not then
-                                    exprasmlist^.concat(new(pai386,op_reg(A_NOT,opsize,p^.location.register)));
-
                                   emit_reg_reg(A_MOV,opsize,p^.right^.location.register,R_EDI);
                                   emit_reg_reg(op,opsize,p^.location.register,R_EDI);
                                   emit_reg_reg(A_MOV,opsize,R_EDI,p^.location.register);
                                end
                              else
                                begin
-                                  if extra_not then
-                                    exprasmlist^.concat(new(pai386,op_reg(A_NOT,opsize,p^.location.register)));
-
                                   exprasmlist^.concat(new(pai386,op_ref_reg(A_MOV,opsize,
                                     newreference(p^.right^.location.reference),R_EDI)));
                                   exprasmlist^.concat(new(pai386,op_reg_reg(op,opsize,p^.location.register,R_EDI)));
@@ -1216,6 +1240,7 @@ implementation
                           end
                         else
                           begin
+                             {
                              if (p^.right^.treetype=ordconstn) and
                                 (op=A_CMP) and
                                 (p^.right^.value=0) then
@@ -1223,20 +1248,6 @@ implementation
                                   exprasmlist^.concat(new(pai386,op_reg_reg(A_TEST,opsize,p^.location.register,
                                     p^.location.register)));
                                end
-                             else if (p^.right^.treetype=ordconstn) and
-                                (op=A_ADD) and
-                                (p^.right^.value=1) then
-                               begin
-                                  exprasmlist^.concat(new(pai386,op_reg(A_INC,opsize,
-                                    p^.location.register)));
-                               end
-                             else if (p^.right^.treetype=ordconstn) and
-                                (op=A_SUB) and
-                                (p^.right^.value=1) then
-                               begin
-                                  exprasmlist^.concat(new(pai386,op_reg(A_DEC,opsize,
-                                    p^.location.register)));
-                               end
                              else if (p^.right^.treetype=ordconstn) and
                                 (op=A_IMUL) and
                                 (ispowerof2(p^.right^.value,power)) then
@@ -1245,37 +1256,21 @@ implementation
                                     p^.location.register)));
                                end
                              else
+                             }
                                begin
                                   if (p^.right^.location.loc=LOC_CREGISTER) then
                                     begin
-                                       if extra_not then
-                                         begin
-                                            emit_reg_reg(A_MOV,S_L,p^.right^.location.register,R_EDI);
-                                            exprasmlist^.concat(new(pai386,op_reg(A_NOT,S_L,R_EDI)));
-                                            emit_reg_reg(A_AND,S_L,R_EDI,
-                                              p^.location.register);
-                                         end
-                                       else
-                                         begin
-                                            emit_reg_reg(op,opsize,p^.right^.location.register,
-                                              p^.location.register);
-                                         end;
+                                       emit_reg_reg(op,opsize,p^.right^.location.register,
+                                          p^.location.register);
                                     end
                                   else
                                     begin
-                                       if extra_not then
-                                         begin
-                                            exprasmlist^.concat(new(pai386,op_ref_reg(A_MOV,S_L,newreference(
-                                              p^.right^.location.reference),R_EDI)));
-                                            exprasmlist^.concat(new(pai386,op_reg(A_NOT,S_L,R_EDI)));
-                                            emit_reg_reg(A_AND,S_L,R_EDI,
-                                              p^.location.register);
-                                         end
-                                       else
-                                         begin
-                                            exprasmlist^.concat(new(pai386,op_ref_reg(op,opsize,newreference(
-                                              p^.right^.location.reference),p^.location.register)));
-                                         end;
+                                       exprasmlist^.concat(new(pai386,op_ref_reg(op,opsize,newreference(
+                                         p^.right^.location.reference),p^.location.registerlow)));
+                                       hr:=newreference(p^.right^.location.reference);
+                                       inc(hr^.offset,4);
+                                       exprasmlist^.concat(new(pai386,op_ref_reg(op2,opsize,
+                                         hr,p^.location.registerhigh)));
                                        ungetiftemp(p^.right^.location.reference);
                                        del_reference(p^.right^.location.reference);
                                     end;
@@ -1287,9 +1282,6 @@ implementation
                         { when swapped another result register }
                         if (p^.treetype=subn) and p^.swaped then
                           begin
-                             if extra_not then
-                               exprasmlist^.concat(new(pai386,op_reg(A_NOT,S_L,p^.location.register)));
-
                              exprasmlist^.concat(new(pai386,op_reg_reg(op,opsize,
                                p^.location.register,p^.right^.location.register)));
                                swap_location(p^.location,p^.right^.location);
@@ -1299,16 +1291,15 @@ implementation
                           end
                         else
                           begin
-                             if extra_not then
-                               exprasmlist^.concat(new(pai386,op_reg(A_NOT,S_L,p^.right^.location.register)));
                              exprasmlist^.concat(new(pai386,op_reg_reg(op,opsize,
                                p^.right^.location.register,
                                p^.location.register)));
+                             exprasmlist^.concat(new(pai386,op_reg_reg(op2,opsize,
+                               p^.right^.location.registerhigh,
+                               p^.location.registerhigh)));
                           end;
-                        case opsize of
-                           S_L : ungetregister32(p^.right^.location.register);
-                           S_B : ungetregister32(reg8toreg32(p^.right^.location.register));
-                        end;
+                        ungetregister32(p^.right^.location.registerlow);
+                        ungetregister32(p^.right^.location.registerhigh);
                      end;
 
                    if cmpop then
@@ -1647,7 +1638,11 @@ implementation
 end.
 {
   $Log$
-  Revision 1.32  1998-12-10 09:47:13  florian
+  Revision 1.33  1998-12-10 11:16:00  florian
+    + some basic operations with qwords and int64 added: +, xor, and, or;
+      the register allocation works fine
+
+  Revision 1.32  1998/12/10 09:47:13  florian
     + basic operations with int64/qord (compiler with -dint64)
     + rtti of enumerations extended: names are now written