diff --git a/.gitattributes b/.gitattributes index faca01aeea..c495d358a1 100644 --- a/.gitattributes +++ b/.gitattributes @@ -674,6 +674,7 @@ compiler/riscv/nrvcnv.pas svneol=native#text/plain compiler/riscv/nrvcon.pas svneol=native#text/plain compiler/riscv/nrvinl.pas svneol=native#text/plain compiler/riscv/nrvset.pas svneol=native#text/plain +compiler/riscv/rarvgas.pas svneol=native#text/plain compiler/riscv/rgcpu.pas svneol=native#text/plain compiler/riscv32/aoptcpu.pas svneol=native#text/plain compiler/riscv32/aoptcpub.pas svneol=native#text/plain diff --git a/compiler/aasmtai.pas b/compiler/aasmtai.pas index 510a2a5883..e124dc5b1e 100644 --- a/compiler/aasmtai.pas +++ b/compiler/aasmtai.pas @@ -368,7 +368,9 @@ interface all assemblers. } asd_cpu, { for the OMF object format } - asd_omf_linnum_line + asd_omf_linnum_line, + { RISC-V } + asd_option ); TAsmSehDirective=( @@ -408,7 +410,9 @@ interface 'code', 'cpu', { for the OMF object format } - 'omf_line' + 'omf_line', + { RISC-V } + 'option' ); sehdirectivestr : array[TAsmSehDirective] of string[16]=( '.seh_proc','.seh_endproc', diff --git a/compiler/assemble.pas b/compiler/assemble.pas index 2ad66ab2cf..0c5da7c9da 100644 --- a/compiler/assemble.pas +++ b/compiler/assemble.pas @@ -1647,6 +1647,10 @@ Implementation { ai_directive(hp).name can be only 16 or 32, this is checked by the reader } ObjData.ThumbFunc:=tai_directive(hp).name='16'; {$endif ARM} +{$ifdef RISCV} + asd_option: + internalerror(2019031701); +{$endif RISCV} else internalerror(2010011101); end; @@ -1800,6 +1804,9 @@ Implementation asd_code: { ignore for now, but should be added} ; + asd_option: + { ignore for now, but should be added} + ; {$ifdef OMFOBJSUPPORT} asd_omf_linnum_line: { ignore for now, but should be added} diff --git a/compiler/fpcdefs.inc b/compiler/fpcdefs.inc index 9090bf4177..693f49e049 100644 --- a/compiler/fpcdefs.inc +++ b/compiler/fpcdefs.inc @@ -275,6 +275,7 @@ {$endif aarch64} {$ifdef riscv32} + {$define riscv} {$define cpu32bit} {$define cpu32bitaddr} {$define cpu32bitalu} @@ -287,6 +288,7 @@ {$endif riscv32} {$ifdef riscv64} + {$define riscv} {$define cpu64bit} {$define cpu64bitaddr} {$define cpu64bitalu} diff --git a/compiler/riscv/rarvgas.pas b/compiler/riscv/rarvgas.pas new file mode 100644 index 0000000000..97bacda10e --- /dev/null +++ b/compiler/riscv/rarvgas.pas @@ -0,0 +1,85 @@ +{ + Copyright (c) 2019 by Jeppe Johansen + + Does the parsing for the RISC-V GNU AS styled inline assembler. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + **************************************************************************** +} +unit rarvgas; + +{$I fpcdefs.inc} + + interface + + uses + raatt, + cpubase; + + type + + trvattreader = class(tattreader) + function is_targetdirective(const s: string): boolean; override; + procedure HandleTargetDirective; override; + end; + + implementation + + uses + { helpers } + cutils, + { global } + globtype,globals,verbose, + systems, + { aasm } + aasmbase,aasmtai,aasmdata,aasmcpu, + { symtable } + symconst,symsym,symdef, + { parser } + procinfo, + rabase,rautils, + cgbase,cgobj,cgrv + ; + + function trvattreader.is_targetdirective(const s: string): boolean; + begin + case s of + '.option': + result:=true + else + Result:=inherited is_targetdirective(s); + end; + end; + + procedure trvattreader.HandleTargetDirective; + var + id: string; + begin + case actasmpattern of + '.option': + begin + consume(AS_TARGET_DIRECTIVE); + id:=actasmpattern; + Consume(AS_ID); + curList.concat(tai_directive.create(asd_option, lower(id))); + end + else + inherited HandleTargetDirective; + end; + end; + +end. + diff --git a/compiler/riscv64/cgcpu.pas b/compiler/riscv64/cgcpu.pas index f8b3888ae9..4b889b3c4d 100644 --- a/compiler/riscv64/cgcpu.pas +++ b/compiler/riscv64/cgcpu.pas @@ -104,6 +104,8 @@ implementation list.Concat(taicpu.op_reg_reg_const(A_ADDIW,reg2,reg1,0)) else if (tosize=OS_S32) and (tcgsize2unsigned[fromsize]=OS_64) then list.Concat(taicpu.op_reg_reg_const(A_ADDIW,reg2,reg1,0)) + else if (tosize=OS_S32) and (fromsize=OS_32) then + list.Concat(taicpu.op_reg_reg_const(A_ADDIW,reg2,reg1,0)) else if (tcgsize2unsigned[tosize]=OS_64) and (fromsize=OS_8) then list.Concat(taicpu.op_reg_reg_const(A_ANDI,reg2,reg1,$FF)) else if (tcgsize2size[fromsize] > tcgsize2size[tosize]) or diff --git a/compiler/riscv64/rarv64gas.pas b/compiler/riscv64/rarv64gas.pas index 2c727846d8..bf92dffc1e 100644 --- a/compiler/riscv64/rarv64gas.pas +++ b/compiler/riscv64/rarv64gas.pas @@ -26,11 +26,11 @@ unit rarv64gas; interface uses - raatt, rarv, + raatt, rarvgas, rarv, cpubase; type - trv64attreader = class(tattreader) + trv64attreader = class(trvattreader) actmemoryordering: TMemoryOrdering; function is_register(const s: string): boolean; override; function is_asmopcode(const s: string):boolean;override; @@ -413,8 +413,10 @@ unit rarv64gas; hl : tasmlabel; ofs : aint; refaddr: trefaddr; + entered_paren: Boolean; Begin expr:=''; + entered_paren:=false; refaddr:=addr_full; if actasmtoken=AS_MOD then @@ -444,6 +446,7 @@ unit rarv64gas; consume(AS_ID); consume(AS_LPAREN); + entered_paren:=true; end; end; @@ -472,6 +475,7 @@ unit rarv64gas; BuildReference(oper); end; + AS_DOT, AS_ID: { A constant expression, or a Variable ref. } Begin if is_fenceflag(actasmpattern) then @@ -553,7 +557,7 @@ unit rarv64gas; { add a constant expression? } if (actasmtoken=AS_PLUS) then begin - l:=BuildConstExpression(true,false); + l:=BuildConstExpression(true,entered_paren); case oper.opr.typ of OPR_CONSTANT : inc(oper.opr.val,l);