From a05aa25aadd53a6e9857e511a82158c782c61678 Mon Sep 17 00:00:00 2001 From: florian Date: Fri, 3 Jun 2022 22:53:44 +0200 Subject: [PATCH] * Risc-V: allow also register aliases in register modification lists after asm blocks, last part to resolve #39738 --- compiler/pstatmnt.pas | 5 +++ compiler/riscv/cpubase.pas | 66 ++++++++++++++++++++++++++++++++++++++ compiler/riscv/rarvgas.pas | 58 ++++----------------------------- tests/webtbs/tw39738.pp | 6 ++++ 4 files changed, 83 insertions(+), 52 deletions(-) create mode 100644 tests/webtbs/tw39738.pp diff --git a/compiler/pstatmnt.pas b/compiler/pstatmnt.pas index 9bd318e888..2ff9dd4a15 100644 --- a/compiler/pstatmnt.pas +++ b/compiler/pstatmnt.pas @@ -1116,6 +1116,11 @@ implementation reg:=std_regnum_search(lower(pattern)) else reg:=NR_NO; + { is_extra_reg is not exported on all architectures from cpubase } +{$if defined(RISCV)} + if (reg=NR_NO) and (token=_CSTRING) then + reg:=is_extra_reg(upper(cstringpattern)); +{$endif defined(RISCV)} if reg<>NR_NO then begin if not(po_assembler in current_procinfo.procdef.procoptions) and assigned(hl) then diff --git a/compiler/riscv/cpubase.pas b/compiler/riscv/cpubase.pas index 05b0db7fbb..d70973dc5f 100644 --- a/compiler/riscv/cpubase.pas +++ b/compiler/riscv/cpubase.pas @@ -441,6 +441,8 @@ uses { 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 is_extra_reg(const s : string) : tregister; + implementation uses @@ -598,4 +600,68 @@ implementation end; end; + + function is_extra_reg(const s: string): tregister; + type + treg2str = record + name : string[4]; + reg : tregister; + end; + + const + extraregs : array[0..32] of treg2str = ( + (name: 'A0'; reg : NR_X10), + (name: 'A1'; reg : NR_X11), + (name: 'A2'; reg : NR_X12), + (name: 'A3'; reg : NR_X13), + (name: 'A4'; reg : NR_X14), + (name: 'A5'; reg : NR_X15), + (name: 'A6'; reg : NR_X16), + (name: 'A7'; reg : NR_X17), + (name: 'ZERO'; reg : NR_X0), + (name: 'RA'; reg : NR_X1), + (name: 'SP'; reg : NR_X2), + (name: 'GP'; reg : NR_X3), + (name: 'TP'; reg : NR_X4), + (name: 'T0'; reg : NR_X5), + (name: 'T1'; reg : NR_X6), + (name: 'T2'; reg : NR_X7), + (name: 'S0'; reg : NR_X8), + (name: 'FP'; reg : NR_X8), + (name: 'S1'; reg : NR_X9), + (name: 'S2'; reg : NR_X18), + (name: 'S3'; reg : NR_X19), + (name: 'S4'; reg : NR_X20), + (name: 'S5'; reg : NR_X21), + (name: 'S6'; reg : NR_X22), + (name: 'S7'; reg : NR_X23), + (name: 'S8'; reg : NR_X24), + (name: 'S9'; reg : NR_X25), + (name: 'S10';reg : NR_X26), + (name: 'S11';reg : NR_X27), + (name: 'T3'; reg : NR_X28), + (name: 'T4'; reg : NR_X29), + (name: 'T5'; reg : NR_X30), + (name: 'T6'; reg : NR_X31) + ); + + var + i : longint; + begin + result:=NR_NO; + { reg found? + possible aliases are always 2 to 4 chars + } + if not (length(s) in [2..4]) then + exit; + for i:=low(extraregs) to high(extraregs) do + begin + if s=extraregs[i].name then + begin + result:=extraregs[i].reg; + exit; + end; + end; + end; + end. diff --git a/compiler/riscv/rarvgas.pas b/compiler/riscv/rarvgas.pas index cc8961bf32..c5690edc5b 100644 --- a/compiler/riscv/rarvgas.pas +++ b/compiler/riscv/rarvgas.pas @@ -30,7 +30,6 @@ unit rarvgas; cpubase; type - trvgasreader = class(tattreader) actmemoryordering: TMemoryOrdering; function is_register(const s: string): boolean; override; @@ -714,68 +713,23 @@ unit rarvgas; instr.Ops:=operandnum; end; + function trvgasreader.is_register(const s: string): boolean; - type - treg2str = record - name : string[4]; - reg : tregister; - end; - - const - extraregs : array[0..32] of treg2str = ( - (name: 'A0'; reg : NR_X10), - (name: 'A1'; reg : NR_X11), - (name: 'A2'; reg : NR_X12), - (name: 'A3'; reg : NR_X13), - (name: 'A4'; reg : NR_X14), - (name: 'A5'; reg : NR_X15), - (name: 'A6'; reg : NR_X16), - (name: 'A7'; reg : NR_X17), - (name: 'ZERO'; reg : NR_X0), - (name: 'RA'; reg : NR_X1), - (name: 'SP'; reg : NR_X2), - (name: 'GP'; reg : NR_X3), - (name: 'TP'; reg : NR_X4), - (name: 'T0'; reg : NR_X5), - (name: 'T1'; reg : NR_X6), - (name: 'T2'; reg : NR_X7), - (name: 'S0'; reg : NR_X8), - (name: 'FP'; reg : NR_X8), - (name: 'S1'; reg : NR_X9), - (name: 'S2'; reg : NR_X18), - (name: 'S3'; reg : NR_X19), - (name: 'S4'; reg : NR_X20), - (name: 'S5'; reg : NR_X21), - (name: 'S6'; reg : NR_X22), - (name: 'S7'; reg : NR_X23), - (name: 'S8'; reg : NR_X24), - (name: 'S9'; reg : NR_X25), - (name: 'S10';reg : NR_X26), - (name: 'S11';reg : NR_X27), - (name: 'T3'; reg : NR_X28), - (name: 'T4'; reg : NR_X29), - (name: 'T5'; reg : NR_X30), - (name: 'T6'; reg : NR_X31) - ); - var - i : longint; - + reg: TRegister; begin result:=inherited is_register(s); { reg found? possible aliases are always 2 to 4 chars } - if result or (not (length(s) in [2..4])) then - exit; - for i:=low(extraregs) to high(extraregs) do + if not(result) then begin - if s=extraregs[i].name then + reg:=is_extra_reg(s); + if reg<>NR_NO then begin - actasmregister:=extraregs[i].reg; + actasmregister:=reg; result:=true; actasmtoken:=AS_REGISTER; - exit; end; end; end; diff --git a/tests/webtbs/tw39738.pp b/tests/webtbs/tw39738.pp new file mode 100644 index 0000000000..bb8769ab29 --- /dev/null +++ b/tests/webtbs/tw39738.pp @@ -0,0 +1,6 @@ +{ %cpu=riscv32,riscv64,riscv128 } +begin + asm + lui t0, 0x06 + end['x5','t1','zero']; +end.