Browse Source

- Fix bug in 64bit softfloat double negation.
- Clean up handling of CPU/FPU type handling in RISCV.
- Do more fixes to get RISCV32 working.
- Fix most soft multiplication handling for generic RISCV code. Still missing a few.
- Add RISCV embedded targets.

git-svn-id: trunk@42335 -

Jeppe Johansen 6 years ago
parent
commit
a1a17447ff

+ 4 - 4
compiler/globals.pas

@@ -536,14 +536,14 @@ interface
         fputype : fpu_x87;
         fputype : fpu_x87;
   {$endif i8086}
   {$endif i8086}
   {$ifdef riscv32}
   {$ifdef riscv32}
-        cputype : cpu_rv32imafd;
-        optimizecputype : cpu_rv32imafd;
+        cputype : cpu_rv32ima;
+        optimizecputype : cpu_rv32ima;
         asmcputype : cpu_none;
         asmcputype : cpu_none;
         fputype : fpu_fd;
         fputype : fpu_fd;
   {$endif riscv32}
   {$endif riscv32}
   {$ifdef riscv64}
   {$ifdef riscv64}
-        cputype : cpu_rv64imafdc;
-        optimizecputype : cpu_rv64imafdc;
+        cputype : cpu_rv64imac;
+        optimizecputype : cpu_rv64imac;
         asmcputype : cpu_none;
         asmcputype : cpu_none;
         fputype : fpu_fd;
         fputype : fpu_fd;
   {$endif riscv64}
   {$endif riscv64}

+ 4 - 0
compiler/ncgmat.pas

@@ -235,7 +235,11 @@ implementation
           OS_32:
           OS_32:
             cg.a_op_const_reg(current_asmdata.CurrAsmList,OP_XOR,OS_32,tcgint($80000000),location.register);
             cg.a_op_const_reg(current_asmdata.CurrAsmList,OP_XOR,OS_32,tcgint($80000000),location.register);
           OS_64:
           OS_64:
+{$ifdef cpu64bitalu}
+            cg.a_op_const_reg(current_asmdata.CurrAsmList,OP_XOR,OS_64,tcgint($80000000),location.register);
+{$else  cpu64bitalu}
             cg.a_op_const_reg(current_asmdata.CurrAsmList,OP_XOR,OS_32,tcgint($80000000),location.registerhi);
             cg.a_op_const_reg(current_asmdata.CurrAsmList,OP_XOR,OS_32,tcgint($80000000),location.registerhi);
+{$endif cpu64bitalu}
         else
         else
           internalerror(2014033101);
           internalerror(2014033101);
         end;
         end;

+ 5 - 7
compiler/options.pas

@@ -4275,21 +4275,19 @@ begin
     begin
     begin
       {$ifdef riscv32}
       {$ifdef riscv32}
       if not option.CPUSetExplicitly then
       if not option.CPUSetExplicitly then
-        init_settings.cputype:=cpu_rv32imafd;
+        init_settings.cputype:=cpu_rv32ima;
       if not option.OptCPUSetExplicitly then
       if not option.OptCPUSetExplicitly then
-        init_settings.optimizecputype:=cpu_rv32imafd;
+        init_settings.optimizecputype:=cpu_rv32ima;
       {$else}
       {$else}
       if not option.CPUSetExplicitly then
       if not option.CPUSetExplicitly then
-        init_settings.cputype:=cpu_rv64imafdc;
+        init_settings.cputype:=cpu_rv64imac;
       if not option.OptCPUSetExplicitly then
       if not option.OptCPUSetExplicitly then
-        init_settings.optimizecputype:=cpu_rv64imafdc;
+        init_settings.optimizecputype:=cpu_rv64imac;
       {$endif}
       {$endif}
 
 
       { Set FPU type }
       { Set FPU type }
       if not(option.FPUSetExplicitly) then
       if not(option.FPUSetExplicitly) then
-        begin
-          init_settings.fputype:=fpu_fd;
-        end
+        init_settings.fputype:=fpu_fd
       else
       else
         begin
         begin
           if not (init_settings.fputype in [fpu_fd]) then
           if not (init_settings.fputype in [fpu_fd]) then

+ 12 - 1
compiler/riscv/agrvgas.pas

@@ -229,9 +229,20 @@ unit agrvgas;
 
 
 
 
     function TRVGNUAssembler.MakeCmdLine: TCmdStr;
     function TRVGNUAssembler.MakeCmdLine: TCmdStr;
+      const
+        arch_str: array[boolean,tcputype] of string[10] = (
+{$ifdef RISCV32}
+          ('','rv32ima','rv32im','rv32i'),
+          ('','rv32imafd','rv32imfd','rv32ifd')
+{$endif RISCV32}
+{$ifdef RISCV64}
+          ('','rv64imac','rv64ima','rv64im','rv64i'),
+          ('','rv64imafdc','rv64imafd','rv64imfd','rv64ifd')
+{$endif RISCV64}
+        );
       begin
       begin
         result := inherited MakeCmdLine;
         result := inherited MakeCmdLine;
-        Replace(result,'$ARCH',lower(cputypestr[current_settings.cputype]));
+        Replace(result,'$ARCH',arch_str[current_settings.fputype=fpu_fd,current_settings.cputype]);
       end;
       end;
 
 
 
 

+ 15 - 2
compiler/riscv/nrvadd.pas

@@ -34,7 +34,9 @@ unit nrvadd;
       trvaddnode = class(tcgaddnode)
       trvaddnode = class(tcgaddnode)
         function pass_1: tnode; override;
         function pass_1: tnode; override;
       protected                            
       protected                            
-        procedure Cmp(signed: boolean);      
+        procedure Cmp(signed: boolean);
+
+        function use_mul_helper: boolean; override;
 
 
         procedure second_cmpsmallset;override;
         procedure second_cmpsmallset;override;
         procedure second_cmpordinal;override;
         procedure second_cmpordinal;override;
@@ -187,7 +189,18 @@ implementation
         else
         else
           Internalerror(2016061101);
           Internalerror(2016061101);
         end;
         end;
-      end;       
+      end;
+
+
+    function trvaddnode.use_mul_helper: boolean;
+      begin
+        if not (CPURV_HAS_MUL in cpu_capabilities[current_settings.cputype]) and
+           (nodetype=muln) and
+           not(torddef(resultdef).ordtype in [u8bit,s8bit]) then
+          result:=true
+        else
+          Result:=inherited use_mul_helper;
+      end;
 
 
 
 
     procedure trvaddnode.second_cmpsmallset;
     procedure trvaddnode.second_cmpsmallset;

+ 20 - 0
compiler/riscv/nrvinl.pas

@@ -210,7 +210,17 @@ implementation
          secondpass(left);
          secondpass(left);
          hlcg.location_force_fpureg(current_asmdata.CurrAsmList,left.location,left.resultdef,true);
          hlcg.location_force_fpureg(current_asmdata.CurrAsmList,left.location,left.resultdef,true);
          location_reset(location,LOC_REGISTER,def_cgsize(resultdef));
          location_reset(location,LOC_REGISTER,def_cgsize(resultdef));
+{$ifdef RISCV32}
+         if (location.size in [OS_S64,OS_64]) then
+           begin
+             location.register64.reglo:=cg.getintregister(current_asmdata.CurrAsmList,OS_32);
+             location.register64.reghi:=cg.getintregister(current_asmdata.CurrAsmList,OS_32);
+           end
+         else
+           location.register:=cg.getintregister(current_asmdata.CurrAsmList,location.size);
+{$else}
          location.register:=cg.getintregister(current_asmdata.CurrAsmList,location.size);
          location.register:=cg.getintregister(current_asmdata.CurrAsmList,location.size);
+{$endif}
          { convert to signed integer rounding towards zero (there's no "round to
          { convert to signed integer rounding towards zero (there's no "round to
            integer using current rounding mode") }
            integer using current rounding mode") }
 
 
@@ -238,7 +248,17 @@ implementation
          secondpass(left);
          secondpass(left);
          hlcg.location_force_fpureg(current_asmdata.CurrAsmList,left.location,left.resultdef,true);
          hlcg.location_force_fpureg(current_asmdata.CurrAsmList,left.location,left.resultdef,true);
          location_reset(location,LOC_REGISTER,def_cgsize(resultdef));
          location_reset(location,LOC_REGISTER,def_cgsize(resultdef));
+{$ifdef RISCV32}
+         if (location.size in [OS_S64,OS_64]) then
+           begin
+             location.register64.reglo:=cg.getintregister(current_asmdata.CurrAsmList,OS_32);
+             location.register64.reghi:=cg.getintregister(current_asmdata.CurrAsmList,OS_32);
+           end
+         else
+           location.register:=cg.getintregister(current_asmdata.CurrAsmList,location.size);
+{$else}
          location.register:=cg.getintregister(current_asmdata.CurrAsmList,location.size);
          location.register:=cg.getintregister(current_asmdata.CurrAsmList,location.size);
+{$endif}
          { convert to signed integer rounding towards zero (there's no "round to
          { convert to signed integer rounding towards zero (there's no "round to
            integer using current rounding mode") }
            integer using current rounding mode") }
 
 

+ 0 - 3
compiler/riscv32/cpuinfo.pas

@@ -37,7 +37,6 @@ Type
    { possible supported processors for this target }
    { possible supported processors for this target }
    tcputype =
    tcputype =
       (cpu_none,
       (cpu_none,
-       cpu_rv32imafd,
        cpu_rv32ima,
        cpu_rv32ima,
        cpu_rv32im,
        cpu_rv32im,
        cpu_rv32i
        cpu_rv32i
@@ -88,7 +87,6 @@ Const
    ];
    ];
 
 
    cputypestr : array[tcputype] of string[10] = ('',
    cputypestr : array[tcputype] of string[10] = ('',
-     'RV32IMAFD',
      'RV32IMA',
      'RV32IMA',
      'RV32IM',
      'RV32IM',
      'RV32I'
      'RV32I'
@@ -126,7 +124,6 @@ Const
  const
  const
    cpu_capabilities : array[tcputype] of set of tcpuflags =
    cpu_capabilities : array[tcputype] of set of tcpuflags =
      ( { cpu_none      } [],
      ( { cpu_none      } [],
-       { cpu_rv32imafd } [CPURV_HAS_MUL,CPURV_HAS_ATOMIC],
        { cpu_rv32ima   } [CPURV_HAS_MUL,CPURV_HAS_ATOMIC],
        { cpu_rv32ima   } [CPURV_HAS_MUL,CPURV_HAS_ATOMIC],
        { cpu_rv32im    } [CPURV_HAS_MUL],
        { cpu_rv32im    } [CPURV_HAS_MUL],
        { cpu_rv32i     } []     
        { cpu_rv32i     } []     

+ 3 - 1
compiler/riscv32/cpupara.pas

@@ -239,7 +239,9 @@ unit cpupara;
 
 
         paraloc:=result.add_location;
         paraloc:=result.add_location;
         { Return in FPU register? }
         { Return in FPU register? }
-        if result.def.typ=floatdef then
+        if (result.def.typ=floatdef) and
+           (not ((cs_fp_emulation in current_settings.moduleswitches) or
+                 (current_settings.fputype in [fpu_soft]))) then
           begin
           begin
             paraloc^.loc:=LOC_FPUREGISTER;
             paraloc^.loc:=LOC_FPUREGISTER;
             paraloc^.register:=NR_FPU_RESULT_REG;
             paraloc^.register:=NR_FPU_RESULT_REG;

+ 3 - 2
compiler/riscv32/nrv32mat.pas

@@ -55,8 +55,8 @@ implementation
       aasmbase,aasmcpu,aasmtai,aasmdata,
       aasmbase,aasmcpu,aasmtai,aasmdata,
       defutil,
       defutil,
       cgutils,cgobj,hlcgobj,pass_2,
       cgutils,cgobj,hlcgobj,pass_2,
+      cpubase,cpuinfo,
       ncon,procinfo,
       ncon,procinfo,
-      cpubase,
       ncgutil,cgcpu;
       ncgutil,cgcpu;
 
 
     procedure trv32notnode.second_boolean;
     procedure trv32notnode.second_boolean;
@@ -121,7 +121,8 @@ implementation
 
 
     function trv32moddivnode.first_moddivint: tnode;
     function trv32moddivnode.first_moddivint: tnode;
       begin
       begin
-        if (not is_64bitint(resultdef)) then
+        if (not is_64bitint(resultdef)) and
+           (CPURV_HAS_MUL in cpu_capabilities[current_settings.cputype]) then
           Result:=nil
           Result:=nil
         else
         else
           result:=inherited;
           result:=inherited;

+ 3 - 6
compiler/riscv64/cpuinfo.pas

@@ -36,8 +36,7 @@ type
 
 
   { possible supported processors for this target }
   { possible supported processors for this target }
   tcputype = (cpu_none,
   tcputype = (cpu_none,
-    cpu_rv64imafdc,
-    cpu_rv64imafd,
+    cpu_rv64imac,
     cpu_rv64ima,
     cpu_rv64ima,
     cpu_rv64im,
     cpu_rv64im,
     cpu_rv64i
     cpu_rv64i
@@ -89,8 +88,7 @@ Const
     ];
     ];
 
 
   cputypestr: array[tcputype] of string[10] = ('',
   cputypestr: array[tcputype] of string[10] = ('',
-    'RV64IMAFDC',
-    'RV64IMAFD',
+    'RV64IMAC',
     'RV64IMA',
     'RV64IMA',
     'RV64IM',
     'RV64IM',
     'RV64I'
     'RV64I'
@@ -128,8 +126,7 @@ Const
  const
  const
    cpu_capabilities : array[tcputype] of set of tcpuflags =
    cpu_capabilities : array[tcputype] of set of tcpuflags =
      ( { cpu_none       } [],
      ( { cpu_none       } [],
-       { cpu_rv64imafdc } [CPURV_HAS_MUL,CPURV_HAS_ATOMIC,CPURV_HAS_COMPACT],
-       { cpu_rv64imafd  } [CPURV_HAS_MUL,CPURV_HAS_ATOMIC],
+       { cpu_rv64imac   } [CPURV_HAS_MUL,CPURV_HAS_ATOMIC,CPURV_HAS_COMPACT],
        { cpu_rv64ima    } [CPURV_HAS_MUL,CPURV_HAS_ATOMIC],
        { cpu_rv64ima    } [CPURV_HAS_MUL,CPURV_HAS_ATOMIC],
        { cpu_rv64im     } [CPURV_HAS_MUL],
        { cpu_rv64im     } [CPURV_HAS_MUL],
        { cpu_rv64i      } []
        { cpu_rv64i      } []

+ 144 - 0
compiler/systems/i_embed.pas

@@ -515,6 +515,140 @@ unit i_embed;
             llvmdatalayout : 'TODO';
             llvmdatalayout : 'TODO';
           );
           );
 
 
+       system_riscv32_embedded_info : tsysteminfo =
+          (
+            system       : system_riscv32_embedded;
+            name         : 'Embedded';
+            shortname    : 'embedded';
+            flags        : [tf_needs_symbol_size,tf_files_case_sensitive,tf_requires_proper_alignment,
+                            tf_smartlink_sections];
+            cpu          : cpu_riscv32;
+            unit_env     : '';
+            extradefines : '';
+            exeext       : '';
+            defext       : '.def';
+            scriptext    : '.sh';
+            smartext     : '.sl';
+            unitext      : '.ppu';
+            unitlibext   : '.ppl';
+            asmext       : '.s';
+            objext       : '.o';
+            resext       : '.res';
+            resobjext    : '.or';
+            sharedlibext : '.so';
+            staticlibext : '.a';
+            staticlibprefix : 'libp';
+            sharedlibprefix : 'lib';
+            sharedClibext : '.so';
+            staticClibext : '.a';
+            staticClibprefix : 'lib';
+            sharedClibprefix : 'lib';
+            importlibprefix : 'libimp';
+            importlibext : '.a';
+            Cprefix      : '';
+            newline      : #10;
+            dirsep       : '/';
+            assem        : as_gas;
+            assemextern  : as_gas;
+            link         : ld_none;
+            linkextern   : ld_embedded;
+            ar           : ar_gnu_ar;
+            res          : res_none;
+            dbg          : dbg_dwarf2;
+            script       : script_unix;
+            endian       : endian_little;
+            alignment    :
+              (
+                procalign       : 4;
+                loopalign       : 4;
+                jumpalign       : 0;
+                jumpalignskipmax    : 0;
+                coalescealign   : 0;
+                coalescealignskipmax: 0;
+                constalignmin   : 0;
+                constalignmax   : 4;
+                varalignmin     : 0;
+                varalignmax     : 4;
+                localalignmin   : 4;
+                localalignmax   : 4;
+                recordalignmin  : 0;
+                recordalignmax  : 4;
+                maxCrecordalign : 4
+              );
+            first_parm_offset : 8;
+            stacksize    : 262144;
+            stackalign   : 4;
+            abi : abi_default;
+            llvmdatalayout : 'e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:64:128-a0:0:64-n32-S32';
+          );
+
+       system_riscv64_embedded_info : tsysteminfo =
+          (
+            system       : system_riscv64_embedded;
+            name         : 'Embedded';
+            shortname    : 'embedded';
+            flags        : [tf_needs_symbol_size,tf_files_case_sensitive,tf_requires_proper_alignment,
+                            tf_smartlink_sections];
+            cpu          : cpu_riscv64;
+            unit_env     : '';
+            extradefines : '';
+            exeext       : '';
+            defext       : '.def';
+            scriptext    : '.sh';
+            smartext     : '.sl';
+            unitext      : '.ppu';
+            unitlibext   : '.ppl';
+            asmext       : '.s';
+            objext       : '.o';
+            resext       : '.res';
+            resobjext    : '.or';
+            sharedlibext : '.so';
+            staticlibext : '.a';
+            staticlibprefix : 'libp';
+            sharedlibprefix : 'lib';
+            sharedClibext : '.so';
+            staticClibext : '.a';
+            staticClibprefix : 'lib';
+            sharedClibprefix : 'lib';
+            importlibprefix : 'libimp';
+            importlibext : '.a';
+            Cprefix      : '';
+            newline      : #10;
+            dirsep       : '/';
+            assem        : as_gas;
+            assemextern  : as_gas;
+            link         : ld_none;
+            linkextern   : ld_embedded;
+            ar           : ar_gnu_ar;
+            res          : res_none;
+            dbg          : dbg_dwarf2;
+            script       : script_unix;
+            endian       : endian_little;
+            alignment    :
+              (
+                procalign       : 4;
+                loopalign       : 4;
+                jumpalign       : 0;
+                jumpalignskipmax    : 0;
+                coalescealign   : 0;
+                coalescealignskipmax: 0;
+                constalignmin   : 0;
+                constalignmax   : 4;
+                varalignmin     : 0;
+                varalignmax     : 4;
+                localalignmin   : 4;
+                localalignmax   : 4;
+                recordalignmin  : 0;
+                recordalignmax  : 4;
+                maxCrecordalign : 4
+              );
+            first_parm_offset : 16;
+            stacksize    : 262144;
+            stackalign   : 8;
+            abi : abi_default;
+            llvmdatalayout : 'e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:64:128-a0:0:64-n32-S32';
+          );
+
   implementation
   implementation
 
 
 initialization
 initialization
@@ -553,4 +687,14 @@ initialization
     set_source_info(system_m68k_embedded_info);
     set_source_info(system_m68k_embedded_info);
   {$endif embedded}
   {$endif embedded}
 {$endif cpum68k}
 {$endif cpum68k}
+{$ifdef cpuriscv32}
+  {$ifdef embedded}
+    set_source_info(system_riscv32_embedded_info);
+  {$endif embedded}
+{$endif cpuriscv32}
+{$ifdef cpuriscv64}
+  {$ifdef embedded}
+    set_source_info(system_riscv64_embedded_info);
+  {$endif embedded}
+{$endif cpuriscv64}
 end.
 end.

+ 10 - 0
compiler/systems/t_embed.pas

@@ -1519,4 +1519,14 @@ initialization
   RegisterLinker(ld_embedded,TLinkerEmbedded);
   RegisterLinker(ld_embedded,TLinkerEmbedded);
   RegisterTarget(system_m68k_embedded_info);
   RegisterTarget(system_m68k_embedded_info);
 {$endif m68k}
 {$endif m68k}
+
+{$ifdef riscv32}
+  RegisterLinker(ld_embedded,TLinkerEmbedded);
+  RegisterTarget(system_riscv32_embedded_info);
+{$endif riscv32}
+
+{$ifdef riscv64}
+  RegisterLinker(ld_embedded,TLinkerEmbedded);
+  RegisterTarget(system_riscv64_embedded_info);
+{$endif riscv64}
 end.
 end.