Browse Source

+ implemented second_int_to_real
* fixed small bug in second_int_to_int

Jonas Maebe 24 years ago
parent
commit
da7d733384
1 changed files with 88 additions and 6 deletions
  1. 88 6
      compiler/powerpc/nppccnv.pas

+ 88 - 6
compiler/powerpc/nppccnv.pas

@@ -41,8 +41,8 @@ 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_cord_to_pointer;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; }
           procedure second_int_to_bool;override;
@@ -164,7 +164,8 @@ implementation
             if opsize in [OS_64,OS_S64] then
               begin
                 location.registerhigh := getregister32;
-                if (opsize = OS_64) then
+                if (opsize = OS_64) or
+                   not (is_signed(left.resulttype.def)) then
                   cg.a_load_const_reg(exprasmlist,OS_32,0,
                     location.registerhigh)
                 else
@@ -172,10 +173,87 @@ implementation
                   exprasmlist.concat(taicpu.op_reg_reg_const(A_SRAWI,
                     location.registerhigh,location.register,31));
               end;
-          end;
+          end
+        else
+          setlocation(location,left.location);
       end;
 
 
+    procedure tppctypeconvnode.second_int_to_real;
+    
+      type
+        dummyrec = record
+          i: int64;
+        end;
+      var
+        tempconst: trealconstnode;
+        ref: treference;
+        valuereg, tempreg, leftreg, tmpfpureg: tregister;
+      begin
+        { the code here comes from the PowerPC Compiler Writer's Guide }
+        
+        { addis R0,R0,0x4330  # R0 = 0x43300000             }
+        { stw R0,disp(R1)     # store upper half            }
+        { xoris R3,R3,0x8000  # flip sign bit               }
+        { stw R3,disp+4(R1)   # store lower half            }
+        { lfd FR1,disp(R1)    # float load double of value  }
+        { fsub FR1,FR1,FR2    # subtract 0x4330000080000000 }
+        gettempofsizereference(8,ref);
+        { we need a certain constant for the conversion, so create it here }
+        tempconst :=
+          { we need this strange typecast because we want the }
+          { double represented by $4330000080000000, not the  }
+          { double converted from the integer with that value }
+          crealconstnode.create(double(dummyrec($4330000080000000)),
+          pbestrealtype^);
+        resulttypepass(tempconst);
+        firstpass(tempconst);
+        secondpass(tempconst);
+        if tempconst.location.loc <> LOC_MEM then
+          internalerror(200110011);
+
+        case left.location.loc of
+          LOC_REGISTER:
+            begin
+              valuereg := left.location.register;
+              leftreg := valuereg;
+            end;
+          LOC_CREGISTER:
+            begin
+              valuereg := cg.get_scratch_reg(exprasmlist);
+              leftreg := valuereg;
+            end;
+          LOC_REFERENCE,LOC_MEM:
+            begin
+              valuereg := cg.get_scratch_reg(exprasmlist);
+              leftreg := valuereg;
+              cg.a_load_ref_reg(exprasmlist,def_cgsize(left.resulttype.def),
+                left.location.reference,valuereg);
+            end
+          else
+            internalerror(200110012);
+         end;
+         tempreg := cg.get_scratch_reg(exprasmlist);
+         exprasmlist.concat(taicpu.op_reg_const(A_LIS,tempreg,$4330));
+         cg.a_load_reg_ref(exprasmlist,OS_32,tempreg,ref);
+         exprasmlist.concat(taicpu.op_reg_reg_const(A_XORIS,valuereg,
+           leftreg,$8000));
+         inc(ref.offset,4);
+         cg.a_load_reg_ref(exprasmlist,OS_32,valuereg,ref);
+         tmpfpureg := get_scratch_reg_fpu(exprasmlist);
+         exprasmlist.concat(taicpu.op_reg_ref(A_LFD,tmpfpureg,tempconst.location.reference));
+         tempconst.free;
+
+         location.register := getregisterfpu;
+         exprasmlist.concat(taicpu.op_reg_ref(A_LFD,location.register,ref));
+         ungetiftemp(ref);
+         
+         exprasmlist.concat(taicpu.op_reg_reg_reg(A_FSUB,location.register,
+           location.register,tmpfpureg));
+         ungetregister(tmpfpureg);
+       end;
+
+
     procedure tppctypeconvnode.second_int_to_bool;
       var
         hreg1,
@@ -231,8 +309,12 @@ begin
 end.
 {
   $Log$
-  Revision 1.1  2001-09-29 21:33:12  jonas
-    + implemented bool_to_int and int_to_int (+ helper in nppcutil)
+  Revision 1.2  2001-10-01 12:17:26  jonas
+    + implemented second_int_to_real
+    * fixed small bug in second_int_to_int
+
+  Revision 1.1  2001/09/29 21:33:12  jonas
+    + implemented in_to_bool and int_to_int (+ helper in nppcutil)
 
 
 }