Jelajahi Sumber

- Add support for .option directive in riscv assembler.
- Use addiw when adjusting U32 to S32

git-svn-id: trunk@41870 -

Jeppe Johansen 6 tahun lalu
induk
melakukan
2b78a8fd3d

+ 1 - 0
.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

+ 6 - 2
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',

+ 7 - 0
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}

+ 2 - 0
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}

+ 85 - 0
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.
+

+ 2 - 0
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

+ 7 - 3
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);