瀏覽代碼

+ SPARC: support FNEGd/FNEGq internal instructions, and use them to implement floating-point negation more efficiently.

git-svn-id: trunk@26259 -
sergei 11 年之前
父節點
當前提交
9a486d73ba
共有 4 個文件被更改,包括 54 次插入32 次删除
  1. 24 32
      compiler/sparc/cpugas.pas
  2. 27 0
      compiler/sparc/ncpumat.pas
  3. 2 0
      compiler/sparc/opcode.inc
  4. 1 0
      compiler/sparc/strinst.inc

+ 24 - 32
compiler/sparc/cpugas.pas

@@ -194,6 +194,23 @@ implementation
 
 
     procedure TSPARCInstrWriter.WriteInstruction(hp:Tai);
+
+      procedure writePseudoInstruction(opc: TAsmOp);
+        begin
+          if (taicpu(hp).ops<>2) or
+             (taicpu(hp).oper[0]^.typ<>top_reg) or
+             (taicpu(hp).oper[1]^.typ<>top_reg) then
+            internalerror(200401045);
+          { Fxxxs %f<even>,%f<even> }
+          owner.AsmWriteln(#9+std_op2str[opc]+#9+getopstr(taicpu(hp).oper[0]^)+','+getopstr(taicpu(hp).oper[1]^));
+          { FMOVs %f<odd>,%f<odd> }
+          inc(taicpu(hp).oper[0]^.reg);
+          inc(taicpu(hp).oper[1]^.reg);
+          owner.AsmWriteln(#9+std_op2str[A_FMOVs]+#9+getopstr(taicpu(hp).oper[0]^)+','+getopstr(taicpu(hp).oper[1]^));
+          dec(taicpu(hp).oper[0]^.reg);
+          dec(taicpu(hp).oper[1]^.reg);
+        end;
+
       var
         Op:TAsmOp;
         s:String;
@@ -206,39 +223,14 @@ implementation
           peephole optimization }
         case op of
           A_FABSd:
-            begin
-              if (taicpu(hp).ops<>2) or
-                 (taicpu(hp).oper[0]^.typ<>top_reg) or
-                 (taicpu(hp).oper[1]^.typ<>top_reg) then
-                internalerror(200401045);
-              { FABSs %f<even>,%f<even> }
-              s:=#9+std_op2str[A_FABSs]+#9+getopstr(taicpu(hp).oper[0]^)+','+getopstr(taicpu(hp).oper[1]^);
-              owner.AsmWriteLn(s);
-              { FMOVs %f<odd>,%f<odd> }
-              inc(taicpu(hp).oper[0]^.reg);
-              inc(taicpu(hp).oper[1]^.reg);
-              s:=#9+std_op2str[A_FMOVs]+#9+getopstr(taicpu(hp).oper[0]^)+','+getopstr(taicpu(hp).oper[1]^);
-              dec(taicpu(hp).oper[0]^.reg);
-              dec(taicpu(hp).oper[1]^.reg);
-              owner.AsmWriteLn(s);
-            end;
+            writePseudoInstruction(A_FABSs);
+
           A_FMOVd:
-            begin
-              if (taicpu(hp).ops<>2) or
-                 (taicpu(hp).oper[0]^.typ<>top_reg) or
-                 (taicpu(hp).oper[1]^.typ<>top_reg) then
-                internalerror(200401045);
-              { FMOVs %f<even>,%f<even> }
-              s:=#9+std_op2str[A_FMOVs]+#9+getopstr(taicpu(hp).oper[0]^)+','+getopstr(taicpu(hp).oper[1]^);
-              owner.AsmWriteLn(s);
-              { FMOVs %f<odd>,%f<odd> }
-              inc(taicpu(hp).oper[0]^.reg);
-              inc(taicpu(hp).oper[1]^.reg);
-              s:=#9+std_op2str[A_FMOVs]+#9+getopstr(taicpu(hp).oper[0]^)+','+getopstr(taicpu(hp).oper[1]^);
-              dec(taicpu(hp).oper[0]^.reg);
-              dec(taicpu(hp).oper[1]^.reg);
-              owner.AsmWriteLn(s);
-            end
+            writePseudoInstruction(A_FMOVs);
+
+          A_FNEGd:
+            writePseudoInstruction(A_FNEGs);
+
           else
             begin
               { call maybe not translated to call }

+ 27 - 0
compiler/sparc/ncpumat.pas

@@ -43,6 +43,10 @@ interface
          procedure second_boolean;override;
       end;
 
+      tsparcunaryminusnode = class(tcgunaryminusnode)
+         procedure second_float; override;
+      end;
+
 implementation
 
     uses
@@ -334,8 +338,31 @@ implementation
       end;
 
 
+{*****************************************************************************
+                                   TSPARCUNARYMINUSNODE
+*****************************************************************************}
+
+    procedure tsparcunaryminusnode.second_float;
+      begin
+        secondpass(left);
+        location_force_fpureg(current_asmdata.CurrAsmList,left.location,true);
+        location_reset(location,LOC_FPUREGISTER,def_cgsize(resultdef));
+        location.register:=cg.getfpuregister(current_asmdata.CurrAsmList,location.size);
+        case location.size of
+          OS_F32:
+            current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_FNEGs,left.location.register,location.register));
+          OS_F64:
+            current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_FNEGd,left.location.register,location.register));
+          OS_F128:
+            current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_FNEGq,left.location.register,location.register));
+        else
+          internalerror(2013030501);
+        end;
+      end;
+
 begin
    cmoddivnode:=tSparcmoddivnode;
    cshlshrnode:=tSparcshlshrnode;
    cnotnode:=tSparcnotnode;
+   cunaryminusnode:=tsparcunaryminusnode;
 end.

+ 2 - 0
compiler/sparc/opcode.inc

@@ -70,6 +70,8 @@ A_tst,
 A_FMOVd,
 A_FABSd,
 A_FABSq,
+A_FNEGd,
+A_FNEGq,
 { Memory barrier instructions }
 A_STBAR,
 A_MEMBAR

+ 1 - 0
compiler/sparc/strinst.inc

@@ -67,6 +67,7 @@
           { internal instructions }
           'fmovd',
           'fabsd','fabsq',
+          'fnegd','fnegq',
           { memory barrier instructions }
           'stbar',
           'membar'