Browse Source

* fixed qword -> <real> type cast

florian 21 years ago
parent
commit
39f5874341
1 changed files with 90 additions and 65 deletions
  1. 90 65
      compiler/x86/nx86cnv.pas

+ 90 - 65
compiler/x86/nx86cnv.pas

@@ -205,79 +205,104 @@ implementation
          href : treference;
          hregister : tregister;
          l1,l2 : tasmlabel;
+         signtested : boolean;
       begin
-         location_reset(location,LOC_FPUREGISTER,def_cgsize(resulttype.def));
-
-         { We need to load from a reference }
-         location_force_mem(exprasmlist,left.location);
-
-         { For u32bit we need to load it as comp and need to
-           make it 64bits }
-         if (torddef(left.resulttype.def).typ=u32bit) then
-           begin
-             tg.GetTemp(exprasmlist,8,tt_normal,href);
-             location_release(exprasmlist,left.location);
-             location_freetemp(exprasmlist,left.location);
-             cg.a_load_ref_ref(exprasmlist,left.location.size,OS_32,left.location.reference,href);
-             inc(href.offset,4);
-             cg.a_load_const_ref(exprasmlist,OS_32,0,href);
-             dec(href.offset,4);
-             left.location.reference:=href;
-           end;
+      {
+        if use_sse(resulttype.def) then
+          begin
+
+          end
+        else
+      }
+          begin
+            location_reset(location,LOC_FPUREGISTER,def_cgsize(resulttype.def));
+            if (left.location.loc=LOC_REGISTER) and (torddef(left.resulttype.def).typ=u64bit) then
+              begin
+{$ifdef cpu64bit}
+                emit_const_reg(A_BT,S_Q,63,left.location.register);
+{$else cpu64bit}
+                emit_const_reg(A_BT,S_L,31,left.location.register64.reghi);
+{$endif cpu64bit}
+                signtested:=true;
+              end
+            else
+              signtested:=false;
+	
+            { We need to load from a reference }
+            location_force_mem(exprasmlist,left.location);
+
+            { For u32bit we need to load it as comp and need to
+              make it 64bits }
+            if (torddef(left.resulttype.def).typ=u32bit) then
+              begin
+                tg.GetTemp(exprasmlist,8,tt_normal,href);
+                location_release(exprasmlist,left.location);
+                location_freetemp(exprasmlist,left.location);
+                cg.a_load_ref_ref(exprasmlist,left.location.size,OS_32,left.location.reference,href);
+                inc(href.offset,4);
+                cg.a_load_const_ref(exprasmlist,OS_32,0,href);
+                dec(href.offset,4);
+                left.location.reference:=href;
+              end;
 
-         { Load from reference to fpu reg }
-         location_release(exprasmlist,left.location);
-         case torddef(left.resulttype.def).typ of
-           u32bit,
-           scurrency,
-           s64bit:
-             exprasmlist.concat(taicpu.op_ref(A_FILD,S_IQ,left.location.reference));
-           u64bit:
-             begin
-                { unsigned 64 bit ints are harder to handle: }
-                { we load bits 0..62 and then check bit 63:  }
-                { if it is 1 then we add $80000000 000000000 }
-                { as double                                  }
-                inc(left.location.reference.offset,4);
-                hregister:=cg.getintregister(exprasmlist,OS_32);
-                cg.a_load_ref_reg(exprasmlist,OS_INT,OS_INT,left.location.reference,hregister);
-                emit_const_ref(A_AND,S_L,$7fffffff,left.location.reference);
-                emit_const_reg(A_TEST,S_L,longint($80000000),hregister);
-                cg.ungetregister(exprasmlist,hregister);
-                dec(left.location.reference.offset,4);
+            { Load from reference to fpu reg }
+            location_release(exprasmlist,left.location);
+            case torddef(left.resulttype.def).typ of
+              u32bit,
+              scurrency,
+              s64bit:
                 exprasmlist.concat(taicpu.op_ref(A_FILD,S_IQ,left.location.reference));
-                objectlibrary.getdatalabel(l1);
-                objectlibrary.getlabel(l2);
-                cg.a_jmp_flags(exprasmlist,F_E,l2);
-                Consts.concat(Tai_label.Create(l1));
-                { I got this constant from a test progtram (FK) }
-                Consts.concat(Tai_const.Create_32bit(0));
-                Consts.concat(Tai_const.Create_32bit(1138753536));
-                reference_reset_symbol(href,l1,0);
-                emit_ref(A_FADD,S_FL,href);
-                cg.a_label(exprasmlist,l2);
-             end
-           else
-             begin
-               if left.resulttype.def.size<4 then
-                 begin
-                   tg.GetTemp(exprasmlist,4,tt_normal,href);
-                   location_freetemp(exprasmlist,left.location);
-                   cg.a_load_ref_ref(exprasmlist,left.location.size,OS_32,left.location.reference,href);
-                   left.location.reference:=href;
-                 end;
-              exprasmlist.concat(taicpu.op_ref(A_FILD,S_IL,left.location.reference));
-             end;
-         end;
-         location_freetemp(exprasmlist,left.location);
-         tcgx86(cg).inc_fpu_stack;
-         location.register:=NR_ST;
+              u64bit:
+                begin
+                   { unsigned 64 bit ints are harder to handle:
+                     we load bits 0..62 and then check bit 63:
+                     if it is 1 then we add $80000000 000000000
+                     as double                                  }
+                   objectlibrary.getdatalabel(l1);
+                   objectlibrary.getlabel(l2);
+
+                   if not(signtested) then
+                     begin
+                       inc(left.location.reference.offset,4);
+                       emit_const_ref(A_BT,S_L,31,left.location.reference);
+                       dec(left.location.reference.offset,4);
+                     end;
+
+                   exprasmlist.concat(taicpu.op_ref(A_FILD,S_IQ,left.location.reference));
+                   cg.a_jmp_flags(exprasmlist,F_NC,l2);
+                   Consts.concat(Tai_label.Create(l1));
+                   { I got this constant from a test program (FK) }
+                   Consts.concat(Tai_const.Create_32bit(0));
+                   Consts.concat(Tai_const.Create_32bit(1138753536));
+                   reference_reset_symbol(href,l1,0);
+                   exprasmList.concat(Taicpu.Op_ref(A_FADD,S_FL,href));
+                   cg.a_label(exprasmlist,l2);
+                end
+              else
+                begin
+                  if left.resulttype.def.size<4 then
+                    begin
+                      tg.GetTemp(exprasmlist,4,tt_normal,href);
+                      location_freetemp(exprasmlist,left.location);
+                      cg.a_load_ref_ref(exprasmlist,left.location.size,OS_32,left.location.reference,href);
+                      left.location.reference:=href;
+                    end;
+                 exprasmlist.concat(taicpu.op_ref(A_FILD,S_IL,left.location.reference));
+                end;
+            end;
+            location_freetemp(exprasmlist,left.location);
+            tcgx86(cg).inc_fpu_stack;
+            location.register:=NR_ST;
+          end;
       end;
 
 end.
 {
   $Log$
-  Revision 1.10  2004-02-27 10:21:06  florian
+  Revision 1.11  2004-05-10 20:57:45  florian
+    * fixed qword -> <real> type cast
+
+  Revision 1.10  2004/02/27 10:21:06  florian
     * top_symbol killed
     + refaddr to treference added
     + refsymbol to treference added