2
0
Эх сурвалжийг харах

* patch by J. Gareth Moreton, issue #36271, part 3: support for the other architectures

git-svn-id: trunk@43441 -
florian 5 жил өмнө
parent
commit
e1e8986462

+ 23 - 0
compiler/aarch64/cpubase.pas

@@ -321,6 +321,9 @@ unit cpubase;
     function inverse_cond(const c: TAsmCond): TAsmCond; {$ifdef USEINLINE}inline;{$endif USEINLINE}
     function inverse_cond(const c: TAsmCond): TAsmCond; {$ifdef USEINLINE}inline;{$endif USEINLINE}
     function conditions_equal(const c1, c2: TAsmCond): boolean; {$ifdef USEINLINE}inline;{$endif USEINLINE}
     function conditions_equal(const c1, c2: TAsmCond): boolean; {$ifdef USEINLINE}inline;{$endif USEINLINE}
 
 
+    { Checks if Subset is a subset of c (e.g. "less than" is a subset of "less than or equal" }
+    function condition_in(const Subset, c: TAsmCond): Boolean;
+
     procedure shifterop_reset(var so : tshifterop); {$ifdef USEINLINE}inline;{$endif USEINLINE}
     procedure shifterop_reset(var so : tshifterop); {$ifdef USEINLINE}inline;{$endif USEINLINE}
 
 
     function dwarf_reg(r:tregister):shortint;
     function dwarf_reg(r:tregister):shortint;
@@ -488,6 +491,26 @@ unit cpubase;
       end;
       end;
 
 
 
 
+    { Checks if Subset is a subset of c (e.g. "less than" is a subset of "less than or equal" }
+    function condition_in(const Subset, c: TAsmCond): Boolean;
+      begin
+        Result := (c = C_None) or conditions_equal(Subset, c);
+
+        { Please update as necessary. [Kit] }
+        if not Result then
+          case Subset of
+            C_EQ:
+              Result := (c in [C_GE, C_LE]);
+            C_LT:
+              Result := (c in [C_LE]);
+            C_GT:
+              Result := (c in [C_GE]);
+            else
+              Result := False;
+          end;
+      end;
+
+
     function dwarf_reg(r:tregister):shortint;
     function dwarf_reg(r:tregister):shortint;
       begin
       begin
         result:=regdwarf_table[findreg_by_number(r)];
         result:=regdwarf_table[findreg_by_number(r)];

+ 23 - 0
compiler/arm/cpubase.pas

@@ -365,6 +365,9 @@ unit cpubase;
     function inverse_cond(const c: TAsmCond): TAsmCond; {$ifdef USEINLINE}inline;{$endif USEINLINE}
     function inverse_cond(const c: TAsmCond): TAsmCond; {$ifdef USEINLINE}inline;{$endif USEINLINE}
     function conditions_equal(const c1, c2: TAsmCond): boolean; {$ifdef USEINLINE}inline;{$endif USEINLINE}
     function conditions_equal(const c1, c2: TAsmCond): boolean; {$ifdef USEINLINE}inline;{$endif USEINLINE}
 
 
+    { Checks if Subset is a subset of c (e.g. "less than" is a subset of "less than or equal" }
+    function condition_in(const Subset, c: TAsmCond): Boolean;
+
     procedure shifterop_reset(var so : tshifterop); {$ifdef USEINLINE}inline;{$endif USEINLINE}
     procedure shifterop_reset(var so : tshifterop); {$ifdef USEINLINE}inline;{$endif USEINLINE}
     function is_pc(const r : tregister) : boolean; {$ifdef USEINLINE}inline;{$endif USEINLINE}
     function is_pc(const r : tregister) : boolean; {$ifdef USEINLINE}inline;{$endif USEINLINE}
 
 
@@ -540,6 +543,26 @@ unit cpubase;
       end;
       end;
 
 
 
 
+    { Checks if Subset is a subset of c (e.g. "less than" is a subset of "less than or equal" }
+    function condition_in(const Subset, c: TAsmCond): Boolean;
+      begin
+        Result := (c = C_None) or conditions_equal(Subset, c);
+
+        { Please update as necessary. [Kit] }
+        if not Result then
+          case Subset of
+            C_EQ:
+              Result := (c in [C_GE, C_LE]);
+            C_LT:
+              Result := (c in [C_LE]);
+            C_GT:
+              Result := (c in [C_GE]);
+            else
+              Result := False;
+          end;
+      end;
+
+
     function is_shifter_const(d : aint;var imm_shift : byte) : boolean;
     function is_shifter_const(d : aint;var imm_shift : byte) : boolean;
       var
       var
          i : longint;
          i : longint;

+ 21 - 0
compiler/avr/cpubase.pas

@@ -300,6 +300,9 @@ unit cpubase;
     function inverse_cond(const c: TAsmCond): TAsmCond; {$ifdef USEINLINE}inline;{$endif USEINLINE}
     function inverse_cond(const c: TAsmCond): TAsmCond; {$ifdef USEINLINE}inline;{$endif USEINLINE}
     function conditions_equal(const c1, c2: TAsmCond): boolean; {$ifdef USEINLINE}inline;{$endif USEINLINE}
     function conditions_equal(const c1, c2: TAsmCond): boolean; {$ifdef USEINLINE}inline;{$endif USEINLINE}
 
 
+    { Checks if Subset is a subset of c (e.g. "less than" is a subset of "less than or equal" }
+    function condition_in(const Subset, c: TAsmCond): Boolean;
+
     function dwarf_reg(r:tregister):byte;
     function dwarf_reg(r:tregister):byte;
     function dwarf_reg_no_error(r:tregister):shortint;
     function dwarf_reg_no_error(r:tregister):shortint;
     function eh_return_data_regno(nr: longint): longint;
     function eh_return_data_regno(nr: longint): longint;
@@ -410,6 +413,24 @@ unit cpubase;
       end;
       end;
 
 
 
 
+    { Checks if Subset is a subset of c (e.g. "less than" is a subset of "less than or equal" }
+    function condition_in(const Subset, c: TAsmCond): Boolean;
+      begin
+        Result := (c = C_None) or conditions_equal(Subset, c);
+
+        { Please update as necessary. [Kit] }
+        if not Result then
+          case Subset of
+            C_EQ:
+              Result := (c in [C_GE]);
+            C_LT:
+              Result := (c in [C_NE]);
+            else
+              Result := False;
+          end;
+      end;
+
+
     function rotl(d : dword;b : byte) : dword;
     function rotl(d : dword;b : byte) : dword;
       begin
       begin
          result:=(d shr (32-b)) or (d shl b);
          result:=(d shr (32-b)) or (d shl b);

+ 24 - 0
compiler/m68k/cpubase.pas

@@ -364,6 +364,10 @@ unit cpubase;
 
 
     function inverse_cond(const c: TAsmCond): TAsmCond; {$ifdef USEINLINE}inline;{$endif USEINLINE}
     function inverse_cond(const c: TAsmCond): TAsmCond; {$ifdef USEINLINE}inline;{$endif USEINLINE}
     function conditions_equal(const c1, c2: TAsmCond): boolean; {$ifdef USEINLINE}inline;{$endif USEINLINE}
     function conditions_equal(const c1, c2: TAsmCond): boolean; {$ifdef USEINLINE}inline;{$endif USEINLINE}
+
+    { Checks if Subset is a subset of c (e.g. "less than" is a subset of "less than or equal" }
+    function condition_in(const Subset, c: TAsmCond): Boolean;
+
     function dwarf_reg(r:tregister):shortint;
     function dwarf_reg(r:tregister):shortint;
     function dwarf_reg_no_error(r:tregister):shortint;
     function dwarf_reg_no_error(r:tregister):shortint;
     function eh_return_data_regno(nr: longint): longint;
     function eh_return_data_regno(nr: longint): longint;
@@ -592,6 +596,26 @@ implementation
     function conditions_equal(const c1, c2: TAsmCond): boolean; {$ifdef USEINLINE}inline;{$endif USEINLINE}
     function conditions_equal(const c1, c2: TAsmCond): boolean; {$ifdef USEINLINE}inline;{$endif USEINLINE}
       begin
       begin
         result := c1 = c2;
         result := c1 = c2;
+    end;
+
+
+    { Checks if Subset is a subset of c (e.g. "less than" is a subset of "less than or equal" }
+    function condition_in(const Subset, c: TAsmCond): Boolean;
+      begin
+        Result := (c = C_None) or conditions_equal(Subset, c);
+
+        { Please update as necessary. [Kit] }
+        if not Result then
+          case Subset of
+            C_EQ:
+              Result := (c in [C_GE, C_LE]);
+            C_LT:
+              Result := (c in [C_LE]);
+            C_GT:
+              Result := (c in [C_GE]);
+            else
+              Result := False;
+          end;
       end;
       end;
 
 
 
 

+ 27 - 0
compiler/mips/cpubase.pas

@@ -259,6 +259,9 @@ unit cpubase;
     function inverse_cond(const c: TAsmCond): TAsmCond; {$ifdef USEINLINE}inline;{$endif USEINLINE}
     function inverse_cond(const c: TAsmCond): TAsmCond; {$ifdef USEINLINE}inline;{$endif USEINLINE}
     function conditions_equal(const c1, c2: TAsmCond): boolean; {$ifdef USEINLINE}inline;{$endif USEINLINE}
     function conditions_equal(const c1, c2: TAsmCond): boolean; {$ifdef USEINLINE}inline;{$endif USEINLINE}
 
 
+    { Checks if Subset is a subset of c (e.g. "less than" is a subset of "less than or equal" }
+    function condition_in(const Subset, c: TAsmCond): Boolean;
+
     { Returns the tcgsize corresponding with the size of reg.}
     { Returns the tcgsize corresponding with the size of reg.}
     function reg_cgsize(const reg: tregister) : tcgsize;
     function reg_cgsize(const reg: tregister) : tcgsize;
     function cgsize2subreg(regtype: tregistertype; s:tcgsize):tsubregister;
     function cgsize2subreg(regtype: tregistertype; s:tcgsize):tsubregister;
@@ -367,6 +370,30 @@ unit cpubase;
       end;
       end;
 
 
 
 
+    { Checks if Subset is a subset of c (e.g. "less than" is a subset of "less than or equal" }
+    function condition_in(const Subset, c: TAsmCond): Boolean;
+      begin
+        Result := (c = C_None) or conditions_equal(Subset, c);
+
+        { Please update as necessary. [Kit] }
+        if not Result then
+          case Subset of
+            C_EQ:
+              Result := (c in [C_GE, C_LE, C_GEU, C_LEU]);
+            C_LT:
+              Result := (c in [C_LE]);
+            C_LTU:
+              Result := (c in [C_LEU]);
+            C_GT:
+              Result := (c in [C_GE]);
+            C_GTU:
+              Result := (c in [C_GEU]);
+            else
+              Result := False;
+          end;
+      end;
+
+
     function std_regnum_search(const s:string):Tregister;
     function std_regnum_search(const s:string):Tregister;
       begin
       begin
         result:=regnumber_table[findreg_by_name_table(s,std_regname_table,std_regname_index)];
         result:=regnumber_table[findreg_by_name_table(s,std_regname_table,std_regname_index)];

+ 14 - 0
compiler/powerpc/cpubase.pas

@@ -395,6 +395,10 @@ uses
 
 
     function inverse_cond(const c: TAsmCond): Tasmcond; {$ifdef USEINLINE}inline;{$endif USEINLINE}
     function inverse_cond(const c: TAsmCond): Tasmcond; {$ifdef USEINLINE}inline;{$endif USEINLINE}
     function conditions_equal(const c1, c2: TAsmCond): boolean;
     function conditions_equal(const c1, c2: TAsmCond): boolean;
+
+    { Checks if Subset is a subset of c (e.g. "less than" is a subset of "less than or equal" }
+    function condition_in(const Subset, c: TAsmCond): Boolean;
+
     function dwarf_reg(r:tregister):shortint;
     function dwarf_reg(r:tregister):shortint;
     function dwarf_reg_no_error(r:tregister):shortint;
     function dwarf_reg_no_error(r:tregister):shortint;
     function eh_return_data_regno(nr: longint): longint;
     function eh_return_data_regno(nr: longint): longint;
@@ -474,6 +478,16 @@ implementation
       end;
       end;
 
 
 
 
+    { Checks if Subset is a subset of c (e.g. "less than" is a subset of "less than or equal" }
+    function condition_in(const Subset, c: TAsmCond): Boolean;
+      begin
+        Result := (c.cond = C_None) or conditions_equal(Subset, c);
+
+        { TODO: Can a PowerPC programmer please update this procedure to
+          actually detect subsets? Thanks. [Kit] }
+      end;
+
+
     function flags_to_cond(const f: TResFlags) : TAsmCond;
     function flags_to_cond(const f: TResFlags) : TAsmCond;
       const
       const
         flag_2_cond: array[F_EQ..F_SO] of TAsmCondFlag =
         flag_2_cond: array[F_EQ..F_SO] of TAsmCondFlag =

+ 14 - 2
compiler/powerpc64/cpubase.pas

@@ -392,9 +392,12 @@ function std_regnum_search(const s: string): Tregister;
 function std_regname(r: Tregister): string;
 function std_regname(r: Tregister): string;
 function is_condreg(r: tregister): boolean;
 function is_condreg(r: tregister): boolean;
 
 
-function inverse_cond(const c: TAsmCond): Tasmcond;
-{$IFDEF USEINLINE}inline;{$ENDIF USEINLINE}
+function inverse_cond(const c: TAsmCond): TAsmCond; {$IFDEF USEINLINE}inline;{$ENDIF USEINLINE}
 function conditions_equal(const c1, c2: TAsmCond): boolean;
 function conditions_equal(const c1, c2: TAsmCond): boolean;
+
+ { Checks if Subset is a subset of c (e.g. "less than" is a subset of "less than or equal" }
+function condition_in(const Subset, c: TAsmCond): Boolean;
+
 function dwarf_reg(r:tregister):shortint;
 function dwarf_reg(r:tregister):shortint;
 function dwarf_reg_no_error(r:tregister):shortint;
 function dwarf_reg_no_error(r:tregister):shortint;
 function eh_return_data_regno(nr: longint): longint;
 function eh_return_data_regno(nr: longint): longint;
@@ -472,6 +475,15 @@ begin
     (c1.crbit = c2.crbit));
     (c1.crbit = c2.crbit));
 end;
 end;
 
 
+{ Checks if Subset is a subset of c (e.g. "less than" is a subset of "less than or equal" }
+function condition_in(const Subset, c: TAsmCond): Boolean;
+  begin
+    Result := (c.cond = C_None) or conditions_equal(Subset, c);
+
+    { TODO: Can a PowerPC programmer please update this procedure to
+      actually detect subsets? Thanks. [Kit] }
+  end;
+
 function flags_to_cond(const f: TResFlags): TAsmCond;
 function flags_to_cond(const f: TResFlags): TAsmCond;
 const
 const
   flag_2_cond: array[F_EQ..F_SO] of TAsmCondFlag =
   flag_2_cond: array[F_EQ..F_SO] of TAsmCondFlag =

+ 19 - 0
compiler/riscv32/cpubase.pas

@@ -333,6 +333,9 @@ uses
 
 
     function conditions_equal(const c1,c2: TAsmCond): boolean;
     function conditions_equal(const c1,c2: TAsmCond): boolean;
 
 
+    { Checks if Subset is a subset of c (e.g. "less than" is a subset of "less than or equal" }
+    function condition_in(const Subset, c: TAsmCond): Boolean;
+
 implementation
 implementation
 
 
     uses
     uses
@@ -459,4 +462,20 @@ implementation
         result:=c1=c2;
         result:=c1=c2;
       end;
       end;
 
 
+
+    { Checks if Subset is a subset of c (e.g. "less than" is a subset of "less than or equal" }
+    function condition_in(const Subset, c: TAsmCond): Boolean;
+      begin
+        Result := (c = C_None) or conditions_equal(Subset, c);
+
+        if not Result then
+          case Subset of
+            C_EQ:
+              Result := (c in [C_GE, C_GEU]);
+            else
+              Result := False;
+          end;
+      end;
+
+
 end.
 end.

+ 18 - 0
compiler/riscv64/cpubase.pas

@@ -348,6 +348,9 @@ const
 
 
     function conditions_equal(const c1,c2: TAsmCond): boolean;
     function conditions_equal(const c1,c2: TAsmCond): boolean;
 
 
+    { Checks if Subset is a subset of c (e.g. "less than" is a subset of "less than or equal" }
+    function condition_in(const Subset, c: TAsmCond): Boolean;
+
 implementation
 implementation
 
 
     uses
     uses
@@ -474,5 +477,20 @@ implementation
         result:=c1=c2;
         result:=c1=c2;
       end;
       end;
 
 
+
+    { Checks if Subset is a subset of c (e.g. "less than" is a subset of "less than or equal" }
+    function condition_in(const Subset, c: TAsmCond): Boolean;
+      begin
+        Result := (c = C_None) or conditions_equal(Subset, c);
+
+        if not Result then
+          case Subset of
+            C_EQ:
+              Result := (c in [C_GE, C_GEU]);
+            else
+              Result := False;
+          end;
+      end;
+
 end.
 end.
 
 

+ 30 - 0
compiler/sparcgen/cpubase.pas

@@ -335,6 +335,9 @@ uses
     function inverse_cond(const c: TAsmCond): TAsmCond; {$ifdef USEINLINE}inline;{$endif USEINLINE}
     function inverse_cond(const c: TAsmCond): TAsmCond; {$ifdef USEINLINE}inline;{$endif USEINLINE}
     function conditions_equal(const c1, c2: TAsmCond): boolean; {$ifdef USEINLINE}inline;{$endif USEINLINE}
     function conditions_equal(const c1, c2: TAsmCond): boolean; {$ifdef USEINLINE}inline;{$endif USEINLINE}
 
 
+    { Checks if Subset is a subset of c (e.g. "less than" is a subset of "less than or equal" }
+    function condition_in(const Subset, c: TAsmCond): Boolean;
+
     function  flags_to_cond(const f: TResFlags) : TAsmCond;
     function  flags_to_cond(const f: TResFlags) : TAsmCond;
     function cgsize2subreg(regtype: tregistertype; s:Tcgsize):Tsubregister;
     function cgsize2subreg(regtype: tregistertype; s:Tcgsize):Tsubregister;
     function reg_cgsize(const reg: tregister): tcgsize;
     function reg_cgsize(const reg: tregister): tcgsize;
@@ -522,6 +525,33 @@ implementation
       end;
       end;
 
 
 
 
+    { Checks if Subset is a subset of c (e.g. "less than" is a subset of "less than or equal" }
+    function condition_in(const Subset, c: TAsmCond): Boolean;
+      begin
+        Result := (c = C_None) or conditions_equal(Subset, c);
+
+        { TODO: Can a SparcGEN programmer please update this procedure to
+          detect all subsets? Thanks. [Kit] }
+        if not Result then
+          case Subset of
+            C_A:
+              Result := (c in [C_A,  C_AE]);
+            C_B:
+              Result := (c in [C_B,  C_BE]);
+            C_E:
+              Result := (c in [C_AE, C_BE]);
+            C_FE:
+              Result := (c in [C_FLE,C_FGE]);
+            C_FL:
+              Result := (c in [C_FLE]);
+            C_FG:
+              Result := (c in [C_FGE]);
+            else
+              Result := False;
+          end;
+      end;
+
+
     function dwarf_reg(r:tregister):shortint;
     function dwarf_reg(r:tregister):shortint;
       begin
       begin
         result:=regdwarf_table[findreg_by_number(r)];
         result:=regdwarf_table[findreg_by_number(r)];

+ 46 - 0
compiler/x86/cpubase.pas

@@ -353,6 +353,9 @@ topsize2memsize: array[topsize] of integer =
     function inverse_cond(const c: TAsmCond): TAsmCond; {$ifdef USEINLINE}inline;{$endif USEINLINE}
     function inverse_cond(const c: TAsmCond): TAsmCond; {$ifdef USEINLINE}inline;{$endif USEINLINE}
     function conditions_equal(const c1, c2: TAsmCond): boolean; {$ifdef USEINLINE}inline;{$endif USEINLINE}
     function conditions_equal(const c1, c2: TAsmCond): boolean; {$ifdef USEINLINE}inline;{$endif USEINLINE}
 
 
+    { Checks if Subset is a subset of c (e.g. "less than" is a subset of "less than or equal" }
+    function condition_in(const Subset, c: TAsmCond): Boolean;
+
     { checks whether two segment registers are normally equal in the current memory model }
     { checks whether two segment registers are normally equal in the current memory model }
     function segment_regs_equal(r1,r2:tregister):boolean;
     function segment_regs_equal(r1,r2:tregister):boolean;
 
 
@@ -666,6 +669,49 @@ implementation
       end;
       end;
 
 
 
 
+    { Checks if Subset is a subset of c (e.g. "less than" is a subset of "less than or equal" }
+    function condition_in(const Subset, c: TAsmCond): Boolean;
+      begin
+        Result := (c = C_None) or conditions_equal(Subset, c);
+        if not Result then
+          case Subset of
+            C_A,  C_NBE:
+              Result := (c in [C_A,  C_AE, C_NB, C_NBE]);
+            C_AE, C_NB:
+              Result := (c in [C_AE, C_NB]);
+            C_B,  C_NAE:
+              Result := (c in [C_B,  C_BE, C_C,  C_NA, C_NAE]);
+            C_BE, C_NA:
+              Result := (c in [C_BE, C_NA]);
+            C_C:
+              { C_B  / C_NAE: CF = 1
+                C_BE / C_NA:  CF = 1 or ZF = 1 }
+              Result := (c in [C_B,  C_BE, C_NA, C_NAE]);
+            C_E,  C_Z:
+              Result := (c in [C_AE, C_BE, C_E,  C_NA, C_NB, C_NG, C_NL]);
+            C_G,  C_NLE:
+              Result := (c in [C_G,  C_GE, C_NL, C_NLE]);
+            C_GE, C_NL:
+              Result := (c in [C_GE, C_NL]);
+            C_L,  C_NGE:
+              Result := (c in [C_L,  C_LE, C_NG, C_NGE]);
+            C_LE, C_NG:
+              Result := (c in [C_LE, C_NG]);
+            C_NC:
+              { C_A  / C_NBE: CF = 0 and ZF = 0; not a subset because ZF has to be zero as well
+                C_AE / C_NB:  CF = 0 }
+              Result := (c in [C_AE, C_NB]);
+            C_NE, C_NZ:
+              Result := (c in [C_NE, C_NZ, C_A,  C_B,  C_NAE,C_NBE,C_L,  C_G,  C_NLE,C_NGE]);
+            C_NP, C_PO:
+              Result := (c in [C_NP, C_PO]);
+            C_P,  C_PE:
+              Result := (c in [C_P,  C_PE]);
+            else
+              Result := False;
+          end;
+      end;
+
     function dwarf_reg(r:tregister):shortint;
     function dwarf_reg(r:tregister):shortint;
       begin
       begin
         result:=regdwarf_table[findreg_by_number(r)];
         result:=regdwarf_table[findreg_by_number(r)];