Explorar o código

* fixed nppccnv and enabled it
- removed PPC specific second_int_to_int and use the generic one instead

Jonas Maebe %!s(int64=23) %!d(string=hai) anos
pai
achega
82e23e60f5
Modificáronse 2 ficheiros con 55 adicións e 129 borrados
  1. 6 1
      compiler/powerpc/cpunode.pas
  2. 49 128
      compiler/powerpc/nppccnv.pas

+ 6 - 1
compiler/powerpc/cpunode.pas

@@ -31,6 +31,7 @@ unit cpunode;
     uses
 //       nppcadd,
 //       nppccal,
+         nppccnv,
 //       nppccon,
 //       nppcflw,
        nppcmat,
@@ -47,7 +48,11 @@ unit cpunode;
 end.
 {
   $Log$
-  Revision 1.5  2002-05-18 13:34:26  peter
+  Revision 1.6  2002-07-11 07:42:31  jonas
+    * fixed nppccnv and enabled it
+    - removed PPC specific second_int_to_int and use the generic one instead
+
+  Revision 1.5  2002/05/18 13:34:26  peter
     * readded missing revisions
 
   Revision 1.4  2002/05/16 19:46:53  carl

+ 49 - 128
compiler/powerpc/nppccnv.pas

@@ -32,8 +32,7 @@ interface
     type
        tppctypeconvnode = class(tcgtypeconvnode)
          protected
-          function first_int_to_int: tnode; override;
-          procedure second_int_to_int;override;
+         { procedure second_int_to_int;override; }
          { procedure second_string_to_string;override; }
          { procedure second_cstring_to_pchar;override; }
          { procedure second_string_to_chararray;override; }
@@ -43,7 +42,7 @@ interface
          { procedure second_chararray_to_string;override; }
          { procedure second_char_to_string;override; }
           procedure second_int_to_real;override;
-         { procedure second_real_to_real;override; }
+          procedure second_real_to_real;override;
          { procedure second_cord_to_pointer;override; }
          { procedure second_proc_to_procvar;override; }
          { procedure second_bool_to_int;override; }
@@ -54,17 +53,17 @@ interface
          { procedure second_class_to_intf;override; }
          { procedure second_char_to_char;override; }
           procedure pass_2;override;
-          procedure second_call_helper(c : tconverttype);
+          procedure second_call_helper(c : tconverttype); override;
        end;
 
 implementation
 
    uses
       verbose,globals,systems,
-      symconst,symdef,aasm,
+      symconst,symdef,aasmbase,aasmtai,
       cgbase,pass_1,pass_2,
       ncon,ncal,
-      cpubase,cpuasm,
+      cpubase,aasmcpu,
       rgobj,tgobj,cgobj,cginfo;
 
 
@@ -105,116 +104,6 @@ implementation
                              SecondTypeConv
 *****************************************************************************}
 
-
-    procedure tppctypeconvnode.second_int_to_int;
-      var
-        fromsize,
-        tosize    : longint;
-        opsize,
-        tempsize  : tcgsize;
-
-      begin
-        { insert range check if not explicit conversion }
-        if not(nf_explizit in flags) then
-          cg.g_rangecheck(exprasmlist,left,resulttype.def);
-
-        fromsize := left.resulttype.def.size;
-        tosize := resulttype.def.size;
-        { is the result size smaller ? }
-        if tosize < fromsize then
-          begin
-            opsize := def_cgsize(resulttype.def);
-            case left.location.loc of
-              LOC_REGISTER,LOC_CREGISTER:
-                begin
-                  if location.loc = LOC_REGISTER then
-                    location.register:= left.location.register
-                  else
-                    location.register := rg.getregisterint(exprasmlist);
-                  case opsize of
-                    OS_8:
-                      exprasmlist.concat(taicpu.op_reg_reg_const_const_const(
-                        A_RLWINM,location.register,left.location.register,
-                        0,24,31));
-                    OS_S8:
-                      exprasmlist.concat(taicpu.op_reg_reg(A_EXTSB,
-                        location.register,left.location.register));
-                    OS_16:
-                      exprasmlist.concat(taicpu.op_reg_reg_const_const_const(
-                        A_RLWINM,location.register,left.location.register,
-                        0,16,31));
-                    OS_S16:
-                      exprasmlist.concat(taicpu.op_reg_reg(A_EXTSH,
-                        location.register,left.location.register));
-                    else
-                      begin
-                        if location.register <> left.location.register then
-                          exprasmlist.concat(taicpu.op_reg_reg(A_MR,
-                            location.register,left.location.register));
-                        { we can release the upper register }
-                        if opsize in [OS_64,OS_S64] then
-                          rg.ungetregister(exprasmlist,left.location.registerhigh);
-                      end;
-                  end;
-                end;
-              LOC_REFERENCE,LOC_CREFERENCE:
-                begin
-                  set_location(location,left.location);
-                  inc(location.reference.offset,fromsize-tosize);
-                end;
-            end;
-          end
-        { is the result size bigger ? }
-        else if resulttype.def.size>left.resulttype.def.size then
-          begin
-            opsize := int_cgsize(fromsize);
-            location.loc := LOC_REGISTER;
-            case left.location.loc of
-              LOC_REFERENCE,LOC_CREFERENCE:
-                begin
-                  reference_release(exprasmlist,left.location.reference);
-                  location.register := rg.getregisterint(exprasmlist);
-                  if not (opsize in [OS_64,OS_S64]) then
-                    tempsize := pred(opsize)
-                  else
-                    tempsize := opsize;
-                  { this one takes care of the necessary sign extensions }
-                  cg.a_load_ref_reg(exprasmlist,tempsize,
-                    left.location.reference,location.register);
-                  tg.ungetiftemp(exprasmlist,left.location.reference);
-                end;
-              LOC_CREGISTER:
-                { since we only have 32bit registers and everything is }
-                { always loaded with sign-extending or zeroeing        }
-                { instructions as appropriate, the source will contain }
-                { the correct value already, so simply copy it         }
-                begin
-                  location.register := rg.getregisterint(exprasmlist);
-                  exprasmlist.concat(taicpu.op_reg_reg(A_MR,location.register,
-                    left.location.register));
-                end;
-              { see LOC_CREGISTER }
-              LOC_REGISTER:;
-            end;
-            { sign extend even further if necessary }
-            if opsize in [OS_64,OS_S64] then
-              begin
-                location.registerhigh := rg.getregisterint(exprasmlist);
-                if (opsize = OS_64) or
-                   not (is_signed(left.resulttype.def)) then
-                  cg.a_load_const_reg(exprasmlist,OS_32,0,
-                    location.registerhigh)
-                else
-                  { duplicate the sign bit 32 times in the high reg }
-                  exprasmlist.concat(taicpu.op_reg_reg_const(A_SRAWI,
-                    location.registerhigh,location.register,31));
-              end;
-          end
-        else
-          set_location(location,left.location);
-      end;
-
-
     procedure tppctypeconvnode.second_int_to_real;
 
       type
@@ -225,8 +114,12 @@ implementation
         tempconst: trealconstnode;
         ref: treference;
         valuereg, tempreg, leftreg, tmpfpureg: tregister;
-        signed: boolean;
+        signed, valuereg_is_scratch: boolean;
       begin
+
+        valuereg_is_scratch := false;
+        location_reset(location,LOC_FPUREGISTER,def_cgsize(resulttype.def));
+
         { the code here comes from the PowerPC Compiler Writer's Guide }
 
         { * longint to double                               }
@@ -278,7 +171,10 @@ implementation
             begin
               leftreg := left.location.register;
               if signed then
-                valuereg := cg.get_scratch_reg_int(exprasmlist)
+                begin
+                  valuereg := cg.get_scratch_reg_int(exprasmlist);
+                  valuereg_is_scratch := true;
+                end
               else
                 valuereg := leftreg;
             end;
@@ -286,6 +182,7 @@ implementation
             begin
               leftreg := cg.get_scratch_reg_int(exprasmlist);
               valuereg := leftreg;
+              valuereg_is_scratch := true;
               cg.a_load_ref_reg(exprasmlist,def_cgsize(left.resulttype.def),
                 left.location.reference,leftreg);
             end
@@ -295,11 +192,15 @@ implementation
          tempreg := cg.get_scratch_reg_int(exprasmlist);
          exprasmlist.concat(taicpu.op_reg_const(A_LIS,tempreg,$4330));
          cg.a_load_reg_ref(exprasmlist,OS_32,tempreg,ref);
+         cg.free_scratch_reg(exprasmlist,tempreg);
          if signed then
            exprasmlist.concat(taicpu.op_reg_reg_const(A_XORIS,valuereg,
-             leftreg,$8000));
+             leftreg,smallint($8000)));
          inc(ref.offset,4);
          cg.a_load_reg_ref(exprasmlist,OS_32,valuereg,ref);
+         dec(ref.offset,4);
+         if (valuereg_is_scratch) then
+           cg.free_scratch_reg(exprasmlist,valuereg);
 
          if (left.location.loc = LOC_REGISTER) or
             ((left.location.loc = LOC_CREGISTER) and
@@ -310,23 +211,40 @@ implementation
 
          tmpfpureg := rg.getregisterfpu(exprasmlist);
          exprasmlist.concat(taicpu.op_reg_ref(A_LFD,tmpfpureg,
-           newreference(tempconst.location.reference)));
+           tempconst.location.reference));
          tempconst.free;
 
          location.register := rg.getregisterfpu(exprasmlist);
          exprasmlist.concat(taicpu.op_reg_ref(A_LFD,location.register,
-           newreference(ref)));
+           ref));
 
-         { restore original offset before ungeting the tempref }
-         dec(ref.offset,4);
          tg.ungetiftemp(exprasmlist,ref);
 
          exprasmlist.concat(taicpu.op_reg_reg_reg(A_FSUB,location.register,
            location.register,tmpfpureg));
          rg.ungetregisterfpu(exprasmlist,tmpfpureg);
+
+         { work around bug in some PowerPC processors }
+         if (tfloatdef(resulttype.def).typ = s32real) then
+           exprasmlist.concat(taicpu.op_reg_reg(A_FRSP,location.register,
+             location.register));
+       end;
+
+
+     procedure tppctypeconvnode.second_real_to_real;
+       begin
+          inherited second_real_to_real;
+          { work around bug in some powerpc processors where doubles aren't }
+          { properly converted to singles                                   }
+          if (tfloatdef(left.resulttype.def).typ = s64real) and
+             (tfloatdef(resulttype.def).typ = s32real) then
+            exprasmlist.concat(taicpu.op_reg_reg(A_FRSP,location.register,
+              location.register));
        end;
 
 
+
+
     procedure tppctypeconvnode.second_int_to_bool;
       var
         hreg1,
@@ -334,17 +252,16 @@ implementation
         resflags : tresflags;
         opsize   : tcgsize;
       begin
-         clear_location(location);
          { byte(boolean) or word(wordbool) or longint(longbool) must }
          { be accepted for var parameters                            }
          if (nf_explizit in flags) and
             (left.resulttype.def.size=resulttype.def.size) and
             (left.location.loc in [LOC_REFERENCE,LOC_CREFERENCE,LOC_CREGISTER]) then
            begin
-              set_location(location,left.location);
+              location_copy(location,left.location);
               exit;
            end;
-         location.loc:=LOC_REGISTER;
+         location_reset(location,LOC_REGISTER,def_cgsize(left.resulttype.def));
          opsize := def_cgsize(left.resulttype.def);
          case left.location.loc of
             LOC_CREFERENCE,LOC_REFERENCE,LOC_REGISTER,LOC_CREGISTER :
@@ -443,7 +360,7 @@ implementation
          if not(convtype in [tc_bool_2_int,tc_bool_2_bool]) then
            begin
               secondpass(left);
-              set_location(location,left.location);
+              location_copy(location,left.location);
               if codegenerror then
                exit;
            end;
@@ -456,7 +373,11 @@ begin
 end.
 {
   $Log$
-  Revision 1.9  2002-05-20 13:30:42  carl
+  Revision 1.10  2002-07-11 07:42:31  jonas
+    * fixed nppccnv and enabled it
+    - removed PPC specific second_int_to_int and use the generic one instead
+
+  Revision 1.9  2002/05/20 13:30:42  carl
   * bugfix of hdisponen (base must be set, not index)
   * more portability fixes