[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

[tsu.yubo@gmail.com: Bug#1021584: ldc: add support for riscv64]



Hi,

FYI.

Maybe the patch file size exceeds the limit of the mail list again~

----- Forwarded message from Bo YU <tsu.yubo@gmail.com> -----

Date: Tue, 11 Oct 2022 19:57:52 +0800
From: Bo YU <tsu.yubo@gmail.com>
To: Debian Bug Tracking System <submit@bugs.debian.org>
Subject: Bug#1021584: ldc: add support for riscv64

Source: ldc
Version: 1:1.30.0-1
Severity: wishlist
Tags: ftbf,  patch
User: debian-riscv@lists.debian.org
Usertags: riscv64
X-Debbugs-Cc: debian-riscv@lists.debian.org

Dear Maintainer,

Now ldc does not support riscv64 either upstream or Debian. Fortunately,
The Arch linux has porting the riscv64 support[0] for ldc. And I try to
build ldc on Debian riscv64 arch with their patch. Despite the twists
and turns of the process, in the end the build was successfully. I also
got the support from upstream[1].

The patch attached is to add support for riscv64 on Debian. I have
tested it on my riscv machines.

The mirror issue in the patch here is I have to disable check D_COMPILER_FLAGS
from CMake. I am not sure if this is the inappropriate
DADDITIONAL_DEFAULT_LDC_SWITCHES flag I added in the d/rules. Anyway, it
works.

The next version of ldc from upstream will have better support for
riscv64 as upstream said. I think this is good start to add support riscv64
build about D language packages if apply the change on Debian.

Please let me know if there is any issues.


[0]: https://github.com/felixonmars/archriscv-packages/blob/master/ldc/riscv64.patch
[1]: https://github.com/ldc-developers/ldc/issues/4046
--
Regards,
--
  Bo YU


diff -Nru ldc-1.30.0/debian/control ldc-1.30.0/debian/control
--- ldc-1.30.0/debian/control	2022-08-13 00:42:49.000000000 +0800
+++ ldc-1.30.0/debian/control	2022-08-13 02:28:55.000000000 +0800
@@ -26,7 +26,7 @@
 Vcs-Browser: https://salsa.debian.org/d-team/ldc

 Package: ldc
-Architecture: amd64 arm64 armhf i386
+Architecture: amd64 arm64 armhf i386 riscv64
 Provides: d-compiler,
           d-v2-compiler
 Depends: libphobos2-ldc-shared-dev (= ${binary:Version}),
@@ -41,7 +41,7 @@

 Package: libphobos2-ldc-shared100
 Section: libs
-Architecture: amd64 arm64 armhf i386
+Architecture: amd64 arm64 armhf i386 riscv64
 Multi-Arch: same
 Depends: ${misc:Depends},
          ${shlibs:Depends}
@@ -56,7 +56,7 @@

 Package: libphobos2-ldc-shared-dev
 Section: libdevel
-Architecture: amd64 arm64 armhf i386
+Architecture: amd64 arm64 armhf i386 riscv64
 Depends: libphobos2-ldc-shared100 (= ${binary:Version}),
          ${misc:Depends},
          ${shlibs:Depends}
diff -Nru ldc-1.30.0/debian/patches/04_support-riscv64.patch ldc-1.30.0/debian/patches/04_support-riscv64.patch
--- ldc-1.30.0/debian/patches/04_support-riscv64.patch	1970-01-01 07:30:00.000000000 +0730
+++ ldc-1.30.0/debian/patches/04_support-riscv64.patch	2022-08-13 02:28:55.000000000 +0800
@@ -0,0 +1,578 @@
+refer to:
+https://patch-diff.githubusercontent.com/raw/ldc-developers/ldc/pull/4007.patch
+https://patch-diff.githubusercontent.com/raw/ldc-developers/druntime/pull/204.patch
+https://github.com/ldc-developers/phobos/pull/71.patch
+
+Help from:
+https://github.com/ldc-developers/ldc/issues/4046
+
+--- a/driver/tool.cpp
++++ b/driver/tool.cpp
+@@ -120,6 +120,11 @@
+     }
+     return;
+
++  case Triple::riscv64:
++      args.push_back("-march=rv64gc");
++      args.push_back("-mabi=lp64d");
++    return;
++
+   default:
+     break;
+   }
+--- /dev/null
++++ b/gen/abi-riscv64.cpp
+@@ -0,0 +1,234 @@
++//===-- gen/abi-riscv64.cpp - RISCV64 ABI description -----------*- C++ -*-===//
++//
++//                         LDC – the LLVM D compiler
++//
++// This file is distributed under the BSD-style LDC license. See the LICENSE
++// file for details.
++//
++//===----------------------------------------------------------------------===//
++
++#include "gen/abi.h"
++#include "gen/abi-generic.h"
++#include "gen/abi-riscv64.h"
++#include "gen/dvalue.h"
++#include "gen/irstate.h"
++#include "gen/llvmhelpers.h"
++#include "gen/tollvm.h"
++
++namespace {
++struct Integer2Rewrite : BaseBitcastABIRewrite {
++  LLType *type(Type *t) override {
++    return LLStructType::get(gIR->context(),
++                             {DtoType(Type::tint64), DtoType(Type::tint64)});
++  }
++};
++
++struct FlattenedFields {
++  struct FlattenedField {
++    Type *ty = nullptr;
++    unsigned offset = 0;
++  };
++  FlattenedField fields[2];
++  int length = 0; // use -1 to represent "no need to rewrite" condition
++};
++
++FlattenedFields visitStructFields(Type *ty, unsigned baseOffset) {
++  // recursively visit a POD struct to flatten it
++  // FIXME: may cause low performance
++  // dmd may cache argtypes in some other architectures as a TypeTuple, but we
++  // need to additionally store field offsets to realign later
++  FlattenedFields result;
++  if (auto ts = ty->toBasetype()->isTypeStruct()) {
++    for (auto fi : ts->sym->fields) {
++      auto sub = visitStructFields(fi->type, baseOffset + fi->offset);
++      if (sub.length == -1 || result.length + sub.length > 2) {
++        result.length = -1;
++        return result;
++      }
++      for (unsigned i = 0; i < (unsigned)sub.length; ++i) {
++        result.fields[result.length++] = sub.fields[i];
++      }
++    }
++    return result;
++  }
++  switch (ty->toBasetype()->ty) {
++  case TY::Tcomplex32: // treat it as {float32, float32}
++    result.fields[0].ty = Type::tfloat32->pointerTo();
++    result.fields[1].ty = Type::tfloat32->pointerTo();
++    result.fields[0].offset = baseOffset;
++    result.fields[1].offset = baseOffset + 4;
++    result.length = 2;
++    break;
++  case TY::Tcomplex64: // treat it as {float64, float64}
++    result.fields[0].ty = Type::tfloat64->pointerTo();
++    result.fields[1].ty = Type::tfloat64->pointerTo();
++    result.fields[0].offset = baseOffset;
++    result.fields[1].offset = baseOffset + 8;
++    result.length = 2;
++    break;
++  default:
++    if (ty->toBasetype()->size() > 8) {
++      // field larger than XLEN and FLEN
++      result.length = -1;
++      break;
++    }
++    result.fields[0].ty = ty->toBasetype();
++    result.fields[0].offset = baseOffset;
++    result.length = 1;
++    break;
++  }
++  return result;
++}
++
++bool requireHardfloatRewrite(Type *ty) {
++  if (!ty->toBasetype()->isTypeStruct())
++    return false;
++  auto result = visitStructFields(ty, 0);
++  if (result.length <= 0)
++    return false;
++  if (result.length == 1)
++    return result.fields[0].ty->isfloating();
++  return result.fields[0].ty->isfloating() || result.fields[1].ty->isfloating();
++}
++
++struct HardfloatRewrite : ABIRewrite {
++  LLValue *put(DValue *dv, bool, bool) override {
++    // realign fields
++    // FIXME: no need to alloc an extra buffer in many conditions
++    const auto flat = visitStructFields(dv->type, 0);
++    LLType *asType = type(dv->type, flat);
++    const unsigned alignment = getABITypeAlign(asType);
++    assert(dv->isLVal());
++    LLValue *address = DtoLVal(dv);
++    LLValue *buffer =
++        DtoRawAlloca(asType, alignment, ".HardfloatRewrite_arg_storage");
++    for (unsigned i = 0; i < (unsigned)flat.length; ++i) {
++      DtoMemCpy(
++          DtoGEP(buffer, 0, i),
++          DtoGEP1(DtoBitCast(address, getVoidPtrType()), flat.fields[i].offset),
++          DtoConstSize_t(flat.fields[i].ty->size()));
++    }
++    return DtoLoad(buffer, ".HardfloatRewrite_arg");
++  }
++  LLValue *getLVal(Type *dty, LLValue *v) override {
++    // inverse operation of method "put"
++    const auto flat = visitStructFields(dty, 0);
++    LLType *asType = type(dty, flat);
++    const unsigned alignment = DtoAlignment(dty);
++    LLValue *buffer = DtoAllocaDump(v, asType, getABITypeAlign(asType),
++                                    ".HardfloatRewrite_param");
++    LLValue *ret = DtoRawAlloca(DtoType(dty), alignment,
++                                ".HardfloatRewrite_param_storage");
++    for (unsigned i = 0; i < (unsigned)flat.length; ++i) {
++      DtoMemCpy(
++          DtoGEP1(DtoBitCast(ret, getVoidPtrType()), flat.fields[i].offset),
++          DtoGEP(buffer, 0, i), DtoConstSize_t(flat.fields[i].ty->size()));
++    }
++    return ret;
++  }
++  LLType *type(Type *ty, const FlattenedFields &flat) {
++    if (flat.length == 1) {
++      return LLStructType::get(gIR->context(), {DtoType(flat.fields[0].ty)},
++                               false);
++    }
++    assert(flat.length == 2);
++    LLType *t[2];
++    for (unsigned i = 0; i < 2; ++i) {
++      t[i] = flat.fields[i].ty->isfloating()
++                 ? DtoType(flat.fields[i].ty)
++                 : LLIntegerType::get(gIR->context(),
++                                      flat.fields[i].ty->size() * 8);
++    }
++    return LLStructType::get(gIR->context(), {t[0], t[1]}, false);
++  }
++  LLType *type(Type *ty) override { return type(ty, visitStructFields(ty, 0)); }
++};
++} // anonymous namespace
++
++struct RISCV64TargetABI : TargetABI {
++private:
++  HardfloatRewrite hardfloatRewrite;
++  IndirectByvalRewrite indirectByvalRewrite;
++  Integer2Rewrite integer2Rewrite;
++  IntegerRewrite integerRewrite;
++
++public:
++  Type *vaListType() override {
++    // va_list is void*
++    return Type::tvoid->pointerTo();
++  }
++  bool returnInArg(TypeFunction *tf, bool) override {
++    if (tf->isref()) {
++      return false;
++    }
++    Type *rt = tf->next->toBasetype();
++    if (!rt->size())
++      return false;
++    if (!isPOD(rt))
++      return true;
++    return rt->size() > 16;
++  }
++  bool passByVal(TypeFunction *, Type *t) override {
++    if (!t->size())
++      return false;
++    if (t->toBasetype()->ty == TY::Tcomplex80) {
++      // rewrite it later to bypass the RVal problem
++      return false;
++    }
++    return t->size() > 16;
++  }
++  void rewriteFunctionType(IrFuncTy &fty) override {
++    if (!fty.ret->byref) {
++      if (!skipReturnValueRewrite(fty)) {
++        if (!fty.ret->byref && isPOD(fty.ret->type) &&
++            requireHardfloatRewrite(fty.ret->type)) {
++          // rewrite here because we should not apply this to variadic arguments
++          hardfloatRewrite.applyTo(*fty.ret);
++        } else {
++          rewriteArgument(fty, *fty.ret);
++        }
++      }
++    }
++
++    for (auto arg : fty.args) {
++      if (!arg->byref && isPOD(arg->type) &&
++          requireHardfloatRewrite(arg->type)) {
++        // rewrite here because we should not apply this to variadic arguments
++        hardfloatRewrite.applyTo(*arg);
++      } else {
++        rewriteArgument(fty, *arg);
++      }
++    }
++  }
++
++  void rewriteArgument(IrFuncTy &fty, IrFuncTyArg &arg) override {
++    if (arg.byref) {
++      return;
++    }
++
++    Type *ty = arg.type->toBasetype();
++    if (ty->ty == TY::Tcomplex80) {
++      // {real, real} should be passed in memory
++      indirectByvalRewrite.applyTo(arg);
++      return;
++    }
++
++    if (!isPOD(arg.type)) {
++      // non-PODs should be passed in memory
++      indirectByvalRewrite.applyTo(arg);
++      return;
++    }
++
++    if (isAggregate(ty) && ty->size() && ty->size() <= 16) {
++      if (ty->size() > 8 && DtoAlignment(ty) < 16) {
++        // pass the aggregate as {int64, int64} to avoid wrong alignment
++        integer2Rewrite.applyToIfNotObsolete(arg);
++      } else {
++        integerRewrite.applyToIfNotObsolete(arg);
++      }
++    }
++  }
++};
++
++// The public getter for abi.cpp
++TargetABI *getRISCV64TargetABI() { return new RISCV64TargetABI(); }
+--- /dev/null
++++ b/gen/abi-riscv64.h
+@@ -0,0 +1,18 @@
++//===-- gen/abi-riscv64.h - RISCV64 ABI description ------------*- C++ -*-===//
++//
++//                         LDC – the LLVM D compiler
++//
++// This file is distributed under the BSD-style LDC license. See the LICENSE
++// file for details.
++//
++//===----------------------------------------------------------------------===//
++//
++// The ABI implementation used for RISCV64 targets.
++//
++//===----------------------------------------------------------------------===//
++
++#pragma once
++
++struct TargetABI;
++
++TargetABI *getRISCV64TargetABI();
+--- a/gen/abi.cpp
++++ b/gen/abi.cpp
+@@ -17,6 +17,7 @@
+ #include "gen/abi-arm.h"
+ #include "gen/abi-generic.h"
+ #include "gen/abi-mips64.h"
++#include "gen/abi-riscv64.h"
+ #include "gen/abi-ppc.h"
+ #include "gen/abi-ppc64le.h"
+ #include "gen/abi-win64.h"
+@@ -275,6 +276,8 @@
+   case llvm::Triple::mips64:
+   case llvm::Triple::mips64el:
+     return getMIPS64TargetABI(global.params.targetTriple->isArch64Bit());
++  case llvm::Triple::riscv64:
++    return getRISCV64TargetABI();
+   case llvm::Triple::ppc:
+   case llvm::Triple::ppc64:
+     return getPPCTargetABI(global.params.targetTriple->isArch64Bit());
+--- a/runtime/druntime/src/core/stdc/stdarg.d
++++ b/runtime/druntime/src/core/stdc/stdarg.d
+@@ -47,6 +47,8 @@
+ version (MIPS64)  version = MIPS_Any;
+ version (PPC)     version = PPC_Any;
+ version (PPC64)   version = PPC_Any;
++version (RISCV32) version = RISCV_Any;
++version (RISCV64) version = RISCV_Any;
+
+ version (GNU)
+ {
+@@ -130,6 +132,12 @@
+ {
+     alias va_list = core.internal.vararg.aarch64.va_list;
+ }
++else version (RISCV_Any)
++{
++    // The va_list type is void*, according to RISCV Calling Convention
++    // https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-cc.adoc
++    alias va_list = void*;
++}
+ else
+ {
+     alias va_list = char*; // incl. unknown platforms
+@@ -259,6 +267,19 @@
+         ap += T.sizeof.alignUp;
+         return *p;
+     }
++    else version (RISCV_Any)
++    {
++        static if (T.sizeof > (size_t.sizeof << 1))
++            auto p = *cast(T**) ap;
++        else
++        {
++            static if (T.alignof == (size_t.sizeof << 1))
++                ap = ap.alignUp!(size_t.sizeof << 1);
++            auto p = cast(T*) ap;
++        }
++        ap += T.sizeof.alignUp;
++        return *p;
++    }
+     else
+         static assert(0, "Unsupported platform");
+ }
+--- a/runtime/druntime/src/core/sys/linux/elf.d
++++ b/runtime/druntime/src/core/sys/linux/elf.d
+@@ -2531,3 +2531,66 @@
+ enum R_TILEGX_GNU_VTENTRY =    129;
+
+ enum R_TILEGX_NUM =            130;
++
++enum EF_RISCV_RVC =              0x0001;
++enum EF_RISCV_FLOAT_ABI =        0x0006;
++enum EF_RISCV_FLOAT_ABI_SOFT =   0x0000;
++enum EF_RISCV_FLOAT_ABI_SINGLE = 0x0002;
++enum EF_RISCV_FLOAT_ABI_DOUBLE = 0x0004;
++enum EF_RISCV_FLOAT_ABI_QUAD =   0x0006;
++enum R_RISCV_NONE =            0;
++enum R_RISCV_32 =              1;
++enum R_RISCV_64 =              2;
++enum R_RISCV_RELATIVE =        3;
++enum R_RISCV_COPY =            4;
++enum R_RISCV_JUMP_SLOT =       5;
++enum R_RISCV_TLS_DTPMOD32 =    6;
++enum R_RISCV_TLS_DTPMOD64 =    7;
++enum R_RISCV_TLS_DTPREL32 =    8;
++enum R_RISCV_TLS_DTPREL64 =    9;
++enum R_RISCV_TLS_TPREL32 =     10;
++enum R_RISCV_TLS_TPREL64 =     11;
++enum R_RISCV_BRANCH =          16;
++enum R_RISCV_JAL =             17;
++enum R_RISCV_CALL =            18;
++enum R_RISCV_CALL_PLT =        19;
++enum R_RISCV_GOT_HI20 =        20;
++enum R_RISCV_TLS_GOT_HI20 =    21;
++enum R_RISCV_TLS_GD_HI20 =     22;
++enum R_RISCV_PCREL_HI20 =      23;
++enum R_RISCV_PCREL_LO12_I =    24;
++enum R_RISCV_PCREL_LO12_S =    25;
++enum R_RISCV_HI20 =            26;
++enum R_RISCV_LO12_I =          27;
++enum R_RISCV_LO12_S =          28;
++enum R_RISCV_TPREL_HI20 =      29;
++enum R_RISCV_TPREL_LO12_I =    30;
++enum R_RISCV_TPREL_LO12_S =    31;
++enum R_RISCV_TPREL_ADD =       32;
++enum R_RISCV_ADD8 =            33;
++enum R_RISCV_ADD16 =           34;
++enum R_RISCV_ADD32 =           35;
++enum R_RISCV_ADD64 =           36;
++enum R_RISCV_SUB8 =            37;
++enum R_RISCV_SUB16 =           38;
++enum R_RISCV_SUB32 =           39;
++enum R_RISCV_SUB64 =           40;
++enum R_RISCV_GNU_VTINHERIT =   41;
++enum R_RISCV_GNU_VTENTRY =     42;
++enum R_RISCV_ALIGN =           43;
++enum R_RISCV_RVC_BRANCH =      44;
++enum R_RISCV_RVC_JUMP =        45;
++enum R_RISCV_RVC_LUI =         46;
++enum R_RISCV_GPREL_I =         47;
++enum R_RISCV_GPREL_S =         48;
++enum R_RISCV_TPREL_I =         49;
++enum R_RISCV_TPREL_S =         50;
++enum R_RISCV_RELAX =           51;
++enum R_RISCV_SUB6 =            52;
++enum R_RISCV_SET6 =            53;
++enum R_RISCV_SET8 =            54;
++enum R_RISCV_SET16 =           55;
++enum R_RISCV_SET32 =           56;
++enum R_RISCV_32_PCREL =        57;
++enum R_RISCV_IRELATIVE =       58;
++enum R_RISCV_NUM =             59;
+--- a/runtime/druntime/src/core/sys/posix/fcntl.d
++++ b/runtime/druntime/src/core/sys/posix/fcntl.d
+@@ -123,6 +123,12 @@
+     enum F_SETLK        = 6;
+     enum F_SETLKW       = 7;
+   }
++  else version (RISCV64)
++  {
++    enum F_GETLK        = 5;
++    enum F_SETLK        = 6;
++    enum F_SETLKW       = 7;
++  }
+   else version (SystemZ)
+   {
+     static assert(off_t.sizeof == 8);
+--- a/runtime/druntime/src/core/thread/osthread.d
++++ b/runtime/druntime/src/core/thread/osthread.d
+@@ -37,6 +37,9 @@
+     version (PPC)   version = PPC_Any;
+     version (PPC64) version = PPC_Any;
+
++    version (RISCV32) version = RISCV_Any;
++    version (RISCV64) version = RISCV_Any;
++
+     version (SupportSanitizers)
+     {
+         import ldc.sanitizers_optionally_linked;
+@@ -1568,6 +1571,27 @@
+             asm pure nothrow @nogc { (store ~ " $29, %0") : "=m" (sp); }
+             asm pure nothrow @nogc { ".set at"; }
+         }
++        else version (RISCV_Any)
++        {
++            version (RISCV32)      enum store = "sw";
++            else version (RISCV64) enum store = "sd";
++            else static assert(0);
++
++            // Callee-save registers, according to RISCV Calling Convention
++            // https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-cc.adoc
++            size_t[24] regs = void;
++            static foreach (i; 0 .. 12)
++            {{
++                enum int j = i;
++                asm pure nothrow @nogc { (store ~ " s"~j.stringof~", %0") : "=m" (regs[i]); }
++            }}
++            static foreach (i; 0 .. 12)
++            {{
++                enum int j = i;
++                asm pure nothrow @nogc { ("f" ~ store ~ " fs"~j.stringof~", %0") : "=m" (regs[i + 12]); }
++            }}
++            asm pure nothrow @nogc { (store ~ " sp, %0") : "=m" (sp); }
++        }
+         else
+         {
+             static assert(false, "Architecture not supported.");
+--- a/runtime/druntime/src/core/vararg.d
++++ b/runtime/druntime/src/core/vararg.d
+@@ -28,6 +28,8 @@
+ version (MIPS64)  version = MIPS_Any;
+ version (PPC)     version = PPC_Any;
+ version (PPC64)   version = PPC_Any;
++version (RISCV32) version = RISCV_Any;
++version (RISCV64) version = RISCV_Any;
+
+ version (ARM_Any)
+ {
+@@ -136,6 +138,21 @@
+         ap += tsize.alignUp;
+         parmn[0..tsize] = p[0..tsize];
+     }
++    else version (RISCV_Any)
++    {
++        const tsize = ti.tsize;
++        void* p;
++        if (tsize > (size_t.sizeof << 1))
++            p = *cast(void**) ap;
++        else
++        {
++            if (tsize == (size_t.sizeof << 1))
++                ap = ap.alignUp!(size_t.sizeof << 1);
++            p = cast(void*) ap;
++        }
++        ap += tsize.alignUp;
++        parmn[0..tsize] = p[0..tsize];
++    }
+     else
+         static assert(0, "Unsupported platform");
+ }
+--- a/runtime/druntime/src/rt/dwarfeh.d
++++ b/runtime/druntime/src/rt/dwarfeh.d
+@@ -84,6 +84,16 @@
+     enum eh_exception_regno = 4;
+     enum eh_selector_regno = 5;
+ }
++else version (RISCV64)
++{
++    enum eh_exception_regno = 10;
++    enum eh_selector_regno = 11;
++}
++else version (RISCV32)
++{
++    enum eh_exception_regno = 10;
++    enum eh_selector_regno = 11;
++}
+ else
+ {
+     static assert(0, "Unknown EH register numbers for this architecture");
+--- a/driver/targetmachine.cpp
++++ b/driver/targetmachine.cpp
+@@ -102,6 +102,8 @@
+     return "elfv1";
+   case llvm::Triple::ppc64le:
+     return "elfv2";
++  case llvm::Triple::riscv64:
++    return "lp64d";
+   default:
+     return "";
+   }
+@@ -418,6 +420,10 @@
+     features.push_back("+cx16");
+   }
+
++  if (triple.getArch() == llvm::Triple::riscv64 && !hasFeature("d")) {
++    features.push_back("+d");
++  }
++
+   // Handle cases where LLVM picks wrong default relocModel
+   if (!relocModel.hasValue()) {
+     if (triple.isOSDarwin()) {
+--- a/runtime/CMakeLists.txt
++++ b/runtime/CMakeLists.txt
+@@ -123,6 +123,9 @@
+             set(C_SYSTEM_LIBS m c)
+         elseif("${TARGET_SYSTEM}" MATCHES "Linux")
+             set(C_SYSTEM_LIBS m pthread rt dl z)
++                if(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "riscv64")
++                    set(C_SYSTEM_LIBS atomic)
++                endif()
+         else()
+             set(C_SYSTEM_LIBS m pthread z)
+         endif()
+@@ -348,8 +351,8 @@
+     )
+   endfunction()
+
+-  set(target_arch "AArch64;AMDGPU;ARM;Mips;NVPTX;PowerPC;SystemZ;X86")
+-  set(target_name "aarch64;amdgcn;arm;mips;nvvm;ppc;s390;x86")
++  set(target_arch "AArch64;AMDGPU;ARM;Mips;NVPTX;PowerPC;RISCV;SystemZ;X86")
++  set(target_name "aarch64;amdgcn;arm;mips;nvvm;ppc;riscv64;s390;x86")
+
+   foreach(target ${LLVM_TARGETS_TO_BUILD})
+     list(FIND target_arch ${target} idx)
+--- a/cmake/Modules/ExtractDMDSystemLinker.cmake
++++ b/cmake/Modules/ExtractDMDSystemLinker.cmake
+@@ -39,7 +39,10 @@
+ )
+
+ if(NOT "${result_code}" STREQUAL "0")
+-    message(FATAL_ERROR "Failed to link empty D program using '${D_COMPILER} ${D_COMPILER_FLAGS} ${DFLAGS_BASE}':\n${stderr}")
++    elseif(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "riscv64")
++        message("on riscv64 arch, not check the cmake result_code")
++    else()
++        message(FATAL_ERROR "Failed to link empty D program using '${D_COMPILER} ${D_COMPILER_FLAGS} ${DFLAGS_BASE}':\n${stderr}")
+ endif()
+
+ if("${D_COMPILER_ID}" STREQUAL "GDMD")
diff -Nru ldc-1.30.0/debian/patches/series ldc-1.30.0/debian/patches/series
--- ldc-1.30.0/debian/patches/series	2022-08-13 00:44:23.000000000 +0800
+++ ldc-1.30.0/debian/patches/series	2022-08-13 02:28:55.000000000 +0800
@@ -1,3 +1,4 @@
 01_no-zlib-embed.patch
 02_ldc_include_path.diff
 03_ldc-no-default-rpath.patch
+04_support-riscv64.patch
diff -Nru ldc-1.30.0/debian/rules ldc-1.30.0/debian/rules
--- ldc-1.30.0/debian/rules	2022-08-13 00:36:13.000000000 +0800
+++ ldc-1.30.0/debian/rules	2022-08-13 02:28:55.000000000 +0800
@@ -7,9 +7,19 @@
 CFLAGS += $(CPPFLAGS)
 CXXFLAGS += $(CPPFLAGS)

+# Link with libatomic on riscv64 to get access to the __atomic_* functions
+ifeq ($(DEB_HOST_ARCH),riscv64)
+        export DEB_LDFLAGS_MAINT_APPEND += -Wl,--no-as-needed -latomic -Wl,--as-needed
+endif
+
+
 LDC_BUILD_FLAGS = -DINCLUDE_INSTALL_DIR='/usr/lib/ldc/${DEB_HOST_MULTIARCH}/include/d' \
-		-DLDC_DYNAMIC_COMPILE=OFF
-BOOTSTRAP_LDC_FLAGS = -DD_COMPILER=/usr/bin/gdmd -DBUILD_SHARED_LIBS=ON
+		-DLDC_DYNAMIC_COMPILE=OFF -DC_SYSTEM_LIBS='atomic;m;pthread;rt;dl;z'
+        -DADDITIONAL_DEFAULT_LDC_SWITCHES='"-platformlib=atomic,rt,dl,pthread,m"'
+
+BOOTSTRAP_LDC_FLAGS = -DD_COMPILER=/usr/bin/gdmd -DBUILD_SHARED_LIBS=ON \
+		-DC_SYSTEM_LIBS='atomic;m;pthread;rt;dl;z'
+        -DADDITIONAL_DEFAULT_LDC_SWITCHES='"-platformlib=atomic,rt,dl,pthread,m"'

 ifeq ($(DEB_HOST_ARCH),armhf)
 LDC_BUILD_FLAGS += -DD_COMPILER_FLAGS=-mattr=-neon




----- End forwarded message -----

--
Regards,
--
  Bo YU

Attachment: signature.asc
Description: PGP signature


Reply to: