From e1e89864620fe33d035b7987c470847d87b808be Mon Sep 17 00:00:00 2001 From: florian Date: Sun, 10 Nov 2019 16:11:40 +0000 Subject: [PATCH] * patch by J. Gareth Moreton, issue #36271, part 3: support for the other architectures git-svn-id: trunk@43441 - --- compiler/aarch64/cpubase.pas | 23 +++++++++++++++++ compiler/arm/cpubase.pas | 23 +++++++++++++++++ compiler/avr/cpubase.pas | 21 ++++++++++++++++ compiler/m68k/cpubase.pas | 24 ++++++++++++++++++ compiler/mips/cpubase.pas | 27 ++++++++++++++++++++ compiler/powerpc/cpubase.pas | 14 +++++++++++ compiler/powerpc64/cpubase.pas | 16 ++++++++++-- compiler/riscv32/cpubase.pas | 19 ++++++++++++++ compiler/riscv64/cpubase.pas | 18 +++++++++++++ compiler/sparcgen/cpubase.pas | 30 ++++++++++++++++++++++ compiler/x86/cpubase.pas | 46 ++++++++++++++++++++++++++++++++++ 11 files changed, 259 insertions(+), 2 deletions(-) diff --git a/compiler/aarch64/cpubase.pas b/compiler/aarch64/cpubase.pas index 2479ca7f1d..f32204d425 100644 --- a/compiler/aarch64/cpubase.pas +++ b/compiler/aarch64/cpubase.pas @@ -321,6 +321,9 @@ unit cpubase; 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} + { 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} function dwarf_reg(r:tregister):shortint; @@ -488,6 +491,26 @@ unit cpubase; 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; begin result:=regdwarf_table[findreg_by_number(r)]; diff --git a/compiler/arm/cpubase.pas b/compiler/arm/cpubase.pas index a61276dc9d..39fbefd45d 100644 --- a/compiler/arm/cpubase.pas +++ b/compiler/arm/cpubase.pas @@ -365,6 +365,9 @@ unit cpubase; 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} + { 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} function is_pc(const r : tregister) : boolean; {$ifdef USEINLINE}inline;{$endif USEINLINE} @@ -540,6 +543,26 @@ unit cpubase; 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; var i : longint; diff --git a/compiler/avr/cpubase.pas b/compiler/avr/cpubase.pas index 20473b0c87..bd35ad51d7 100644 --- a/compiler/avr/cpubase.pas +++ b/compiler/avr/cpubase.pas @@ -300,6 +300,9 @@ unit cpubase; 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} + { 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_no_error(r:tregister):shortint; function eh_return_data_regno(nr: longint): longint; @@ -410,6 +413,24 @@ unit cpubase; 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; begin result:=(d shr (32-b)) or (d shl b); diff --git a/compiler/m68k/cpubase.pas b/compiler/m68k/cpubase.pas index 97edabdb51..6e9f4b2031 100644 --- a/compiler/m68k/cpubase.pas +++ b/compiler/m68k/cpubase.pas @@ -364,6 +364,10 @@ unit cpubase; 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} + + { 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_no_error(r:tregister):shortint; 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} begin 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; diff --git a/compiler/mips/cpubase.pas b/compiler/mips/cpubase.pas index 46b6098cfd..e06cbe6a2a 100644 --- a/compiler/mips/cpubase.pas +++ b/compiler/mips/cpubase.pas @@ -259,6 +259,9 @@ unit cpubase; 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} + { 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.} function reg_cgsize(const reg: tregister) : tcgsize; function cgsize2subreg(regtype: tregistertype; s:tcgsize):tsubregister; @@ -367,6 +370,30 @@ unit cpubase; 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; begin result:=regnumber_table[findreg_by_name_table(s,std_regname_table,std_regname_index)]; diff --git a/compiler/powerpc/cpubase.pas b/compiler/powerpc/cpubase.pas index 9bbd89b1a2..55d838c4cb 100644 --- a/compiler/powerpc/cpubase.pas +++ b/compiler/powerpc/cpubase.pas @@ -395,6 +395,10 @@ uses function inverse_cond(const c: TAsmCond): Tasmcond; {$ifdef USEINLINE}inline;{$endif USEINLINE} 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_no_error(r:tregister):shortint; function eh_return_data_regno(nr: longint): longint; @@ -474,6 +478,16 @@ implementation 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; const flag_2_cond: array[F_EQ..F_SO] of TAsmCondFlag = diff --git a/compiler/powerpc64/cpubase.pas b/compiler/powerpc64/cpubase.pas index 06315423fa..e5a7bb3aa5 100644 --- a/compiler/powerpc64/cpubase.pas +++ b/compiler/powerpc64/cpubase.pas @@ -392,9 +392,12 @@ function std_regnum_search(const s: string): Tregister; function std_regname(r: Tregister): string; 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; + + { 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_no_error(r:tregister):shortint; function eh_return_data_regno(nr: longint): longint; @@ -472,6 +475,15 @@ begin (c1.crbit = c2.crbit)); 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; const flag_2_cond: array[F_EQ..F_SO] of TAsmCondFlag = diff --git a/compiler/riscv32/cpubase.pas b/compiler/riscv32/cpubase.pas index 1e9e63a127..1be96d8ea6 100644 --- a/compiler/riscv32/cpubase.pas +++ b/compiler/riscv32/cpubase.pas @@ -333,6 +333,9 @@ uses 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 uses @@ -459,4 +462,20 @@ implementation 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); + + if not Result then + case Subset of + C_EQ: + Result := (c in [C_GE, C_GEU]); + else + Result := False; + end; + end; + + end. diff --git a/compiler/riscv64/cpubase.pas b/compiler/riscv64/cpubase.pas index 48fcffc9a7..74abee3d2c 100644 --- a/compiler/riscv64/cpubase.pas +++ b/compiler/riscv64/cpubase.pas @@ -348,6 +348,9 @@ const 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 uses @@ -474,5 +477,20 @@ implementation 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); + + if not Result then + case Subset of + C_EQ: + Result := (c in [C_GE, C_GEU]); + else + Result := False; + end; + end; + end. diff --git a/compiler/sparcgen/cpubase.pas b/compiler/sparcgen/cpubase.pas index f82291f5fc..32c38711a6 100644 --- a/compiler/sparcgen/cpubase.pas +++ b/compiler/sparcgen/cpubase.pas @@ -335,6 +335,9 @@ uses 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} + { 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 cgsize2subreg(regtype: tregistertype; s:Tcgsize):Tsubregister; function reg_cgsize(const reg: tregister): tcgsize; @@ -522,6 +525,33 @@ implementation 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; begin result:=regdwarf_table[findreg_by_number(r)]; diff --git a/compiler/x86/cpubase.pas b/compiler/x86/cpubase.pas index eaba70be32..5d34c7550f 100644 --- a/compiler/x86/cpubase.pas +++ b/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 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 } function segment_regs_equal(r1,r2:tregister):boolean; @@ -666,6 +669,49 @@ implementation 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; begin result:=regdwarf_table[findreg_by_number(r)];