Browse Source

* synchronized with trunk

git-svn-id: branches/wasm@48429 -
nickysn 4 years ago
parent
commit
541b8e183d

+ 24 - 20
compiler/m68k/aoptcpu.pas

@@ -253,26 +253,30 @@ unit aoptcpu;
               opstr:=opname(p);
               opstr:=opname(p);
               case taicpu(p).oper[0]^.typ of
               case taicpu(p).oper[0]^.typ of
                 top_reg:
                 top_reg:
-                  begin
-                    {  move %reg0, %tmpreg; move %tmpreg, <ea> -> move %reg0, <ea> }
-                    taicpu(p).loadOper(1,taicpu(next).oper[1]^);
-                    asml.remove(next);
-                    next.free;
-                    result:=true;
-                    { also remove leftover move %reg0, %reg0, which can occur as the result
-                      of the previous optimization, if %reg0 and %tmpreg was different types
-                      (addr vs. data), so these moves were left in by the cg }
-                    if MatchOperand(taicpu(p).oper[0]^,taicpu(p).oper[1]^) then
-                      begin
-                        DebugMsg('Optimizer: '+opstr+' + '+opstr+' removed',p);
-                        GetNextInstruction(p,next);
-                        asml.remove(p);
-                        p.free;
-                        p:=next;
-                      end
-                    else
-                      DebugMsg('Optimizer: '+opstr+' + '+opstr+' to '+opstr+' #1',p)
-                  end;
+                  { do not optimize away FPU to INT to FPU reg moves. These are used for 
+                    to-single-rounding on FPUs which have no FSMOVE/FDMOVE. (KB) }
+                  if not ((taicpu(p).opcode = A_FMOVE) and
+                    (getregtype(taicpu(p).oper[0]^.reg) <> getregtype(taicpu(p).oper[1]^.reg))) then
+                    begin
+                      {  move %reg0, %tmpreg; move %tmpreg, <ea> -> move %reg0, <ea> }
+                      taicpu(p).loadOper(1,taicpu(next).oper[1]^);
+                      asml.remove(next);
+                      next.free;
+                      result:=true;
+                      { also remove leftover move %reg0, %reg0, which can occur as the result
+                        of the previous optimization, if %reg0 and %tmpreg was different types
+                        (addr vs. data), so these moves were left in by the cg }
+                      if MatchOperand(taicpu(p).oper[0]^,taicpu(p).oper[1]^) then
+                        begin
+                          DebugMsg('Optimizer: '+opstr+' + '+opstr+' removed',p);
+                          GetNextInstruction(p,next);
+                          asml.remove(p);
+                          p.free;
+                          p:=next;
+                        end
+                      else
+                        DebugMsg('Optimizer: '+opstr+' + '+opstr+' to '+opstr+' #1',p)
+                    end;
                 top_const:
                 top_const:
                   begin
                   begin
                     // DebugMsg('Optimizer: '+opstr+' + '+opstr+' to '+opstr+' #2',p);
                     // DebugMsg('Optimizer: '+opstr+' + '+opstr+' to '+opstr+' #2',p);

+ 35 - 3
compiler/m68k/cgcpu.pas

@@ -1051,10 +1051,40 @@ unit cgcpu;
     procedure tcg68k.a_loadfpu_reg_reg(list: TAsmList; fromsize, tosize: tcgsize; reg1, reg2: tregister);
     procedure tcg68k.a_loadfpu_reg_reg(list: TAsmList; fromsize, tosize: tcgsize; reg1, reg2: tregister);
       var
       var
         instr : taicpu;
         instr : taicpu;
+        op: tasmop;
+        href: treference;
+        hreg: tregister;
       begin
       begin
-        instr:=taicpu.op_reg_reg(A_FMOVE,fpuregopsize,reg1,reg2);
-        add_move_instruction(instr);
-        list.concat(instr);
+        if fromsize > tosize then
+          begin
+            { we have to do a load-store through an intregister or the stack in this case,
+              which is probably the fastest way, and simpler than messing around with FPU control
+              words for one-off custom rounding (KB) }
+            case tosize of
+              OS_F32:
+                  begin
+                    //list.concat(tai_comment.create(strpnew('a_loadfpu_reg_reg rounding via intreg')));
+                    hreg := getintregister(list,OS_32);
+                    list.concat(taicpu.op_reg_reg(A_FMOVE, tcgsize2opsize[tosize], reg1, hreg));
+                    list.concat(taicpu.op_reg_reg(A_FMOVE, tcgsize2opsize[tosize], hreg, reg2));
+                  end;
+            else
+              begin
+                //list.concat(tai_comment.create(strpnew('a_loadfpu_reg_reg rounding via stack')));
+                reference_reset_base(href, NR_STACK_POINTER_REG, 0, ctempposinvalid, 0, []);
+                href.direction:=dir_dec;
+                list.concat(taicpu.op_reg_ref(A_FMOVE, tcgsize2opsize[tosize], reg1, href));
+                href.direction:=dir_inc;
+                list.concat(taicpu.op_ref_reg(A_FMOVE, tcgsize2opsize[tosize], href, reg2));
+              end;
+            end;
+          end
+        else
+          begin
+            instr:=taicpu.op_reg_reg(A_FMOVE,fpuregopsize,reg1,reg2);
+            add_move_instruction(instr);
+            list.concat(instr);
+          end;
       end;
       end;
 
 
 
 
@@ -1067,6 +1097,8 @@ unit cgcpu;
         href := ref;
         href := ref;
         fixref(list,href,current_settings.fputype = fpu_coldfire);
         fixref(list,href,current_settings.fputype = fpu_coldfire);
         list.concat(taicpu.op_ref_reg(A_FMOVE,opsize,href,reg));
         list.concat(taicpu.op_ref_reg(A_FMOVE,opsize,href,reg));
+        if fromsize > tosize then
+          a_load_reg_reg(list,fromsize,tosize,reg,reg);
       end;
       end;
 
 
     procedure tcg68k.a_loadfpu_reg_ref(list: TAsmList; fromsize,tosize: tcgsize; reg: tregister; const ref: treference);
     procedure tcg68k.a_loadfpu_reg_ref(list: TAsmList; fromsize,tosize: tcgsize; reg: tregister; const ref: treference);

+ 8 - 13
compiler/m68k/n68kadd.pas

@@ -26,7 +26,7 @@ unit n68kadd;
 interface
 interface
 
 
     uses
     uses
-       symtype,node,nadd,ncgadd,cpubase,cgbase;
+       node,nadd,ncgadd,cpubase,cgbase;
 
 
 
 
     type
     type
@@ -34,7 +34,7 @@ interface
        private
        private
           function getresflags(unsigned: boolean) : tresflags;
           function getresflags(unsigned: boolean) : tresflags;
           function getfloatresflags: tresflags;
           function getfloatresflags: tresflags;
-          function inlineable_realconstnode(const n: tnode; fpu_type : tdef): boolean;
+          function inlineable_realconstnode(const n: tnode): boolean;
           procedure second_mul64bit;
           procedure second_mul64bit;
        protected
        protected
           function use_generic_mul64bit: boolean; override;
           function use_generic_mul64bit: boolean; override;
@@ -55,7 +55,7 @@ implementation
     uses
     uses
       globtype,systems,
       globtype,systems,
       cutils,verbose,globals,
       cutils,verbose,globals,
-      symconst,symdef,paramgr,
+      symconst,symdef,paramgr,symtype,
       aasmbase,aasmtai,aasmdata,aasmcpu,defutil,htypechk,
       aasmbase,aasmtai,aasmdata,aasmcpu,defutil,htypechk,
       cpuinfo,pass_1,pass_2,
       cpuinfo,pass_1,pass_2,
       cpupara,cgutils,procinfo,
       cpupara,cgutils,procinfo,
@@ -146,14 +146,9 @@ implementation
       end;
       end;
 
 
 
 
-    function t68kaddnode.inlineable_realconstnode(const n: tnode; fpu_type : tdef): boolean;
+    function t68kaddnode.inlineable_realconstnode(const n: tnode): boolean;
       begin
       begin
-        if assigned(fpu_type) and
-	   ((FPUM68K_HAS_EXTENDED in fpu_capabilities[current_settings.fputype])
-            or (fpu_type.size < sizeof(bestreal))) then
-          result:=false
-        else
-          result:=(n.nodetype = realconstn) and
+        result:=(n.nodetype = realconstn) and
             not ((trealconstnode(n).value_real=MathInf.Value) or
             not ((trealconstnode(n).value_real=MathInf.Value) or
                  (trealconstnode(n).value_real=MathNegInf.Value) or
                  (trealconstnode(n).value_real=MathNegInf.Value) or
                  (trealconstnode(n).value_real=MathQNaN.value));
                  (trealconstnode(n).value_real=MathQNaN.value));
@@ -196,7 +191,7 @@ implementation
 
 
         { have left in the register, right can be a memory location }
         { have left in the register, right can be a memory location }
         if (FPUM68K_HAS_FLOATIMMEDIATE in fpu_capabilities[current_settings.fputype]) and
         if (FPUM68K_HAS_FLOATIMMEDIATE in fpu_capabilities[current_settings.fputype]) and
-           inlineable_realconstnode(left,resultdef) then
+           inlineable_realconstnode(left) then
           begin
           begin
             location.register := cg.getfpuregister(current_asmdata.CurrAsmList,location.size);
             location.register := cg.getfpuregister(current_asmdata.CurrAsmList,location.size);
             current_asmdata.CurrAsmList.concat(taicpu.op_realconst_reg(A_FMOVE,tcgsize2opsize[left.location.size],trealconstnode(left).value_real,location.register))
             current_asmdata.CurrAsmList.concat(taicpu.op_realconst_reg(A_FMOVE,tcgsize2opsize[left.location.size],trealconstnode(left).value_real,location.register))
@@ -216,7 +211,7 @@ implementation
           LOC_REFERENCE,LOC_CREFERENCE:
           LOC_REFERENCE,LOC_CREFERENCE:
               begin
               begin
                 if (FPUM68K_HAS_FLOATIMMEDIATE in fpu_capabilities[current_settings.fputype]) and
                 if (FPUM68K_HAS_FLOATIMMEDIATE in fpu_capabilities[current_settings.fputype]) and
-                   inlineable_realconstnode(right,resultdef) then
+                   inlineable_realconstnode(right) then
                   current_asmdata.CurrAsmList.concat(taicpu.op_realconst_reg(op,tcgsize2opsize[right.location.size],trealconstnode(right).value_real,location.register))
                   current_asmdata.CurrAsmList.concat(taicpu.op_realconst_reg(op,tcgsize2opsize[right.location.size],trealconstnode(right).value_real,location.register))
                 else
                 else
                   begin
                   begin
@@ -289,7 +284,7 @@ implementation
                   begin
                   begin
                     hlcg.location_force_fpureg(current_asmdata.CurrAsmList,left.location,left.resultdef,true);
                     hlcg.location_force_fpureg(current_asmdata.CurrAsmList,left.location,left.resultdef,true);
                     if not (current_settings.fputype = fpu_coldfire) and
                     if not (current_settings.fputype = fpu_coldfire) and
-                       inlineable_realconstnode(right,left.resultdef) then
+                       inlineable_realconstnode(right) then
                       current_asmdata.CurrAsmList.concat(taicpu.op_realconst_reg(A_FCMP,tcgsize2opsize[right.location.size],trealconstnode(right).value_real,left.location.register))
                       current_asmdata.CurrAsmList.concat(taicpu.op_realconst_reg(A_FCMP,tcgsize2opsize[right.location.size],trealconstnode(right).value_real,left.location.register))
                     else
                     else
                       begin
                       begin

+ 3 - 3
packages/fcl-registry/tests/regtcxmlreg.pp

@@ -94,13 +94,13 @@ begin
   SetLength(S1,100);
   SetLength(S1,100);
   For I:=0 to 99 do
   For I:=0 to 99 do
     S1[I]:=i;
     S1[I]:=i;
-  XMLReg.SetValueData('b',dtBinary,S1[1],Length(S1));
+  XMLReg.SetValueData('b',dtBinary,S1[0],Length(S1));
   XMLReg.Flush;
   XMLReg.Flush;
-  DS:=SizeOf(S1) div 4;
+  DS:=Length(S1) div 4;
   SetLength(S2,DS);
   SetLength(S2,DS);
   For I:=0 to DS-1 do
   For I:=0 to DS-1 do
     S2[I]:=i;
     S2[I]:=i;
-  AssertEquals('Cannot read, buffer size too small',False,XMLReg.GetValueData('b',dt,S2[1],ds));
+  AssertEquals('Cannot read, buffer size too small',False,XMLReg.GetValueData('b',dt,S2[0],DS));
   AssertTrue('Correct data type reported',dt=dtBinary);
   AssertTrue('Correct data type reported',dt=dtBinary);
   AssertEquals('Correct data buffer size reported',Length(S1),DS);
   AssertEquals('Correct data buffer size reported',Length(S1),DS);
 end;
 end;

+ 38 - 2
packages/pasjpeg/examples/example.pas

@@ -1,3 +1,8 @@
+{$IFDEF FPC}
+{$MODE DELPHI}
+{$GOTO ON}
+{$DEFINE DELPHI_STREAM}
+{$ENDIF}
 Unit example;
 Unit example;
 
 
 { This file illustrates how to use the IJG code as a subroutine library
 { This file illustrates how to use the IJG code as a subroutine library
@@ -37,6 +42,10 @@ function read_JPEG_file (filename : string) : boolean;
 
 
 implementation
 implementation
 
 
+{$ifdef delphi_stream}
+  uses
+    Classes;
+{$endif delphi_stream}
 { <setjmp.h> is used for the optional error recovery mechanism shown in
 { <setjmp.h> is used for the optional error recovery mechanism shown in
   the second part of the example. }
   the second part of the example. }
 
 
@@ -93,7 +102,11 @@ var
 
 
   jerr : jpeg_error_mgr;
   jerr : jpeg_error_mgr;
   { More stuff }
   { More stuff }
+{$ifdef delphi_stream}
+  outfile : TFileStream;
+{$else delphi_stream}
   outfile : FILE;               { target file }
   outfile : FILE;               { target file }
+{$endif delphi_stream}
   row_pointer : array[0..0] of JSAMPROW ;       { pointer to JSAMPLE row[s] }
   row_pointer : array[0..0] of JSAMPROW ;       { pointer to JSAMPLE row[s] }
   row_stride : int;             { physical row width in image buffer }
   row_stride : int;             { physical row width in image buffer }
 begin
 begin
@@ -117,7 +130,9 @@ begin
     stdio stream.  You can also write your own code to do something else.
     stdio stream.  You can also write your own code to do something else.
     VERY IMPORTANT: use "b" option to fopen() if you are on a machine that
     VERY IMPORTANT: use "b" option to fopen() if you are on a machine that
     requires it in order to write binary files. }
     requires it in order to write binary files. }
-
+{$ifdef delphi_stream}
+  outfile := TFileStream.Create(filename, fmCreate);
+{$else delphi_stream}
   Assign(outfile, filename);
   Assign(outfile, filename);
   {$push}{$I-}
   {$push}{$I-}
   ReWrite(outfile, 1);
   ReWrite(outfile, 1);
@@ -127,6 +142,7 @@ begin
     WriteLn(output, 'can''t open ', filename);
     WriteLn(output, 'can''t open ', filename);
     Halt(1);
     Halt(1);
   end;
   end;
+{$endif delphi_stream}
   jpeg_stdio_dest(@cinfo, @outfile);
   jpeg_stdio_dest(@cinfo, @outfile);
 
 
   { Step 3: set parameters for compression }
   { Step 3: set parameters for compression }
@@ -179,7 +195,11 @@ begin
 
 
   jpeg_finish_compress(@cinfo);
   jpeg_finish_compress(@cinfo);
   { After finish_compress, we can close the output file. }
   { After finish_compress, we can close the output file. }
+{$ifdef delphi_stream}
+  outfile.Free;
+{$else delphi_stream}
   system.close(outfile);
   system.close(outfile);
+{$endif delphi_stream}
 
 
   { Step 7: release JPEG compression object }
   { Step 7: release JPEG compression object }
 
 
@@ -321,7 +341,11 @@ var
 
 
   jerr  : my_error_mgr;
   jerr  : my_error_mgr;
   { More stuff }
   { More stuff }
-  infile : FILE;                { source file }
+{$ifdef delphi_stream}
+  infile : TFileStream;
+{$else delphi_stream}
+  infile : FILE;               { target file }
+{$endif delphi_stream}
   buffer : JSAMPARRAY;          { Output row buffer }
   buffer : JSAMPARRAY;          { Output row buffer }
   row_stride : int;             { physical row width in output buffer }
   row_stride : int;             { physical row width in output buffer }
 begin
 begin
@@ -331,6 +355,9 @@ begin
     VERY IMPORTANT: use "b" option to fopen() if you are on a machine that
     VERY IMPORTANT: use "b" option to fopen() if you are on a machine that
     requires it in order to read binary files. }
     requires it in order to read binary files. }
 
 
+{$ifdef delphi_stream}
+  infile := TFileStream.Create(filename, fmOpenRead);
+{$else delphi_stream}
   Assign(infile, filename);
   Assign(infile, filename);
   {$push}{$I-}
   {$push}{$I-}
   Reset(infile, 1);
   Reset(infile, 1);
@@ -341,6 +368,7 @@ begin
     read_JPEG_file := FALSE;
     read_JPEG_file := FALSE;
     exit;
     exit;
   end;
   end;
+{$endif delphi_stream}
 
 
   { Step 1: allocate and initialize JPEG decompression object }
   { Step 1: allocate and initialize JPEG decompression object }
 
 
@@ -356,7 +384,11 @@ begin
     { Nomssi: if we get here, we are in trouble, because e.g. cinfo.mem
     { Nomssi: if we get here, we are in trouble, because e.g. cinfo.mem
               is not guaranted to be NIL }
               is not guaranted to be NIL }
     jpeg_destroy_decompress(@cinfo);
     jpeg_destroy_decompress(@cinfo);
+{$ifdef delphi_stream}
+    infile.Free;
+{$else delphi_stream}
     system.close(infile);
     system.close(infile);
+{$endif delphi_stream}
     read_JPEG_file := FALSE;
     read_JPEG_file := FALSE;
     exit;
     exit;
   end;
   end;
@@ -440,7 +472,11 @@ begin
     Here we postpone it until after no more JPEG errors are possible,
     Here we postpone it until after no more JPEG errors are possible,
     so as to simplify the setjmp error logic above.  (Actually, I don't
     so as to simplify the setjmp error logic above.  (Actually, I don't
     think that jpeg_destroy can do an error exit, but why assume anything...) }
     think that jpeg_destroy can do an error exit, but why assume anything...) }
+{$ifdef delphi_stream}
+  infile.Free;
+{$else delphi_stream}
   system.close(infile);
   system.close(infile);
+{$endif delphi_stream}
 
 
   { At this point you may want to check to see whether any corrupt-data
   { At this point you may want to check to see whether any corrupt-data
     warnings occurred (test whether jerr.pub.num_warnings is nonzero). }
     warnings occurred (test whether jerr.pub.num_warnings is nonzero). }