Custom toolcahin config to support semi hosting and softfloats

Bypass-Presubmit-Reason: No presubmit configured

Change-Id: Id7af89c3c7e1ebc83de3a4955d454cfbcb5147ab
diff --git a/.bazelrc b/.bazelrc
new file mode 100644
index 0000000..d34c052
--- /dev/null
+++ b/.bazelrc
@@ -0,0 +1,3 @@
+# Use our custom-configured c++ toolchain, using --crosstol_top or --cpu as a differentiator.
+build:kelvin_rvv_rv32_toolchain_config --crosstool_top=//toolchain:kelvin_rvv
+build:kelvin_rvv_rv32_toolchain_config --cpu=kelvin_rvv_rv32
\ No newline at end of file
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..f31c400
--- /dev/null
+++ b/README.md
@@ -0,0 +1,27 @@
+# Bazel Kelcin Toolchain
+Repo containing RISC-V toochain configuration for Kelvin. 
+
+## Usage {: #usage}
+
+This is work in progress bazel repo: please reach out to me for additional questions and suggestions.
+
+## Build and try it yoursself
+
+1.  If you have not already done so, [download and install Bazel 6.2.1](https://bazel.build/install) or later.
+
+2. TBD for toolchain download instrcutions
+
+3. Run the build with the following command:
+
+    ```bash
+     bazel-6.2.1 run -s --config=kelvin_rvv_rv32_toolchain_config //examples:hello-world-add-floats
+    ```
+    You can also build rvv_add_intrinsic.
+
+4.  The above command builds hell-world-add-floats target with custom toolchain defined under toolcahins.
+    Note: TBD add instrcutions to build the toochain from sracth
+
+5.  Execute binary with mpact_sim
+    ```bash
+    {$PATH_TO_MPACT_SIM}/bazel-bin/riscv/rv32gv_sim   --semihost_arm=true  bazel-bin/hello-world-add-floats
+    ```
\ No newline at end of file
diff --git a/WORKSPACE.bazel b/WORKSPACE.bazel
new file mode 100644
index 0000000..18c7661
--- /dev/null
+++ b/WORKSPACE.bazel
@@ -0,0 +1,2 @@
+load("//toolchain:repo.bzl", "crt_repos")
+crt_repos()
\ No newline at end of file
diff --git a/examples/BUILD b/examples/BUILD
new file mode 100644
index 0000000..5721335
--- /dev/null
+++ b/examples/BUILD
@@ -0,0 +1,9 @@
+cc_binary(
+    name = "hello-world-add-floats",
+    srcs = ["hello-world-add-floats.cc"],
+)
+
+cc_binary(
+    name = "rvv_add_intrinsic",
+    srcs = ["rvv_add_intrinsic.cc"],
+)
diff --git a/examples/hello-world-add-floats.cc b/examples/hello-world-add-floats.cc
new file mode 100644
index 0000000..b11cb21
--- /dev/null
+++ b/examples/hello-world-add-floats.cc
@@ -0,0 +1,17 @@
+#include <stdio.h>
+#include <string.h>
+
+int main() {
+  float input1[8] = {1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0};
+  float input2[8] = {1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0};
+  float output[8];
+
+  printf(" Added input1 and input 2 results are follwing\n ");
+  for (int i = 0; i < 8; i++) {
+    output[i] = input1[i] + input2[i];
+    printf(" %d ", static_cast<int>(output[i]));
+  }
+  // flush
+  printf("\n");
+  return 0;
+}
diff --git a/examples/rvv_add_intrinsic.cc b/examples/rvv_add_intrinsic.cc
new file mode 100644
index 0000000..e1b52a5
--- /dev/null
+++ b/examples/rvv_add_intrinsic.cc
@@ -0,0 +1,30 @@
+#include <riscv_vector.h>
+#include <stdio.h>
+#include <string.h>
+
+int8_t input_1[1024];
+int8_t input_2[1024];
+int16_t output[1024];
+
+int main() {
+  unsigned vlen = __riscv_vlenb();
+  memset(input_1, 1, 1024);
+  memset(input_2, 6, 1024);
+  const int8_t* input1_ptr = &input_1[0];
+  const int8_t* input2_ptr = &input_2[0];
+  int16_t* output_ptr = &output[0];
+
+  for (int idx = 0; (idx + 31) < 1024; idx += 32) {
+    vint8m4_t input_v2 = __riscv_vle8_v_i8m4(input2_ptr + idx, 32);
+    vint8m4_t input_v1 = __riscv_vle8_v_i8m4(input1_ptr + idx, 32);
+
+    vint16m8_t temp_sum = __riscv_vwadd_vv_i16m8(input_v1, input_v2, 32);
+    __riscv_vse16_v_i16m8(output_ptr + idx, temp_sum, 32);
+  }
+
+  printf("printing 1st 10 values of output");
+  for (int i = 0; i < 10; i++) {
+    printf(" %d ", output[i]);
+  }
+  return 0;
+}
diff --git a/toolchain/BUILD b/toolchain/BUILD
new file mode 100644
index 0000000..307e27c
--- /dev/null
+++ b/toolchain/BUILD
@@ -0,0 +1,35 @@
+package(default_visibility = ["//visibility:public"])
+
+load(":cc_toolchain_config.bzl", "cc_kelvin_rvv_rv32_toolchain_config")
+
+filegroup(
+    name="all_files_toolchain",
+    srcs = glob(["out/*/**"])
+)
+
+cc_kelvin_rvv_rv32_toolchain_config(
+   name = "kelvin_rvv_rv32_toolchain_config",
+)
+
+cc_toolchain_suite(
+    name="kelvin_rvv",
+    toolchains = {
+        "kelvin_rvv_rv32": ":kelvin_rvv_rv32_toolchain",
+    }
+
+)
+
+cc_toolchain(
+    name = "kelvin_rvv_rv32_toolchain",
+    toolchain_identifier = "kelvin_rvv_rv32-toolchain",
+    toolchain_config = ":kelvin_rvv_rv32_toolchain_config",
+    all_files = ":all_files_toolchain",
+    as_files = ":all_files_toolchain",
+    ar_files = ":all_files_toolchain",
+    compiler_files = ":all_files_toolchain",
+    dwp_files = ":all_files_toolchain",
+    linker_files = ":all_files_toolchain",
+    objcopy_files = ":all_files_toolchain",
+    strip_files = ":all_files_toolchain",
+    supports_param_files = 0,
+)
\ No newline at end of file
diff --git a/toolchain/cc_toolchain_config.bzl b/toolchain/cc_toolchain_config.bzl
new file mode 100644
index 0000000..7a2d1c1
--- /dev/null
+++ b/toolchain/cc_toolchain_config.bzl
@@ -0,0 +1,143 @@
+load("@bazel_tools//tools/build_defs/cc:action_names.bzl", "ACTION_NAMES")
+load(
+    "@bazel_tools//tools/cpp:cc_toolchain_config_lib.bzl",
+    "tool_path",
+    "feature",
+    "feature_set",
+    "flag_group",
+    "flag_set",
+    )
+
+load(
+    "@crt//config:features.bzl",
+    "CPP_ALL_COMPILE_ACTIONS",
+    "C_ALL_COMPILE_ACTIONS",
+    "LD_ALL_ACTIONS",
+)
+
+
+def _impl(ctx):
+    tool_paths = [ # NEW
+        tool_path(
+            name = "gcc",
+            path = "out/bin/riscv32-unknown-elf-g++",
+        ),
+        tool_path(
+            name = "ld",
+            path = "out/bin/riscv32-unknown-elf-ld",
+        ),
+        tool_path(
+            name = "ar",
+            path = "out/bin/riscv32-unknown-elf-gcc-ar",
+        ),
+        tool_path(
+            name = "cpp",
+            path = "out/bin/riscv32-unknown-elf-c++",
+        ),
+        tool_path(
+            name = "gcov",
+            path = "/bin/false",
+        ),
+        tool_path(
+            name = "nm",
+            path = "/bin/false",
+        ),
+        tool_path(
+            name = "objdump",
+            path = "/bin/false",
+        ),
+        tool_path(
+            name = "strip",
+            path = "/bin/false",
+        ),
+    ]
+    includes_feature = feature(
+        name = "includes",
+        enabled = True,
+        flag_sets = [
+            flag_set(
+                actions = [
+                    ACTION_NAMES.assemble,
+                    ACTION_NAMES.preprocess_assemble,
+                    ACTION_NAMES.linkstamp_compile,
+                    ACTION_NAMES.c_compile,
+                    ACTION_NAMES.cpp_compile,
+                    ACTION_NAMES.cpp_header_parsing,
+                    ACTION_NAMES.cpp_module_compile,
+                    ACTION_NAMES.cpp_module_codegen,
+                    ACTION_NAMES.lto_backend,
+                    ACTION_NAMES.clif_match
+                ],
+                flag_groups = [
+                    flag_group(
+                        flags = [
+                            "-nostdinc",
+                            "-u", "_printf_float",
+                            "-lsemihosting",
+                            "-isystem", "toolchain/out/riscv32-unknown-elf/include",
+                            "-isystem", "toolchain/out/lib/gcc/riscv32-unknown-elf/15.0.1/include"
+                        ],
+                    ),
+                ],
+            ),
+        ],
+
+     )
+
+    sys_feature = feature(
+        name = "sys_spec",
+        enabled = True,
+        flag_sets = [
+            flag_set(
+                actions = CPP_ALL_COMPILE_ACTIONS,
+                flag_groups = [
+                    flag_group(
+                        flags = [
+                            "-march=rv32im_zve32x_zicsr",
+                            "-mabi=ilp32",
+                            "-mcmodel=medany",
+                        ],
+                    ),
+                ],
+            ),
+            flag_set(
+                actions = LD_ALL_ACTIONS,
+                flag_groups = [
+                    flag_group(
+                        flags = [
+                            "--specs=semihost.specs",
+                            "-lsemihost",
+                            "-lm",
+                            "-lc",
+                            "-lgcc",
+                        ],
+                    ),
+                ],
+            ),
+        ],
+    )
+
+    return cc_common.create_cc_toolchain_config_info(
+        ctx= ctx,
+        toolchain_identifier = "kelvin_rvv_rv32-toolchain",
+        host_system_name = "kelvin_v2",
+        target_system_name = "kelvin_rvv_rv32",
+        target_cpu = "kelvin_rvv_rv32",
+        target_libc = "newlib",
+        compiler = "clang",
+        abi_version = "ilp32 ",
+        abi_libc_version="ilp32",
+         features = [
+             includes_feature,
+             sys_feature,
+         ],
+        tool_paths = tool_paths,
+    )
+
+cc_kelvin_rvv_rv32_toolchain_config = rule(
+    implementation = _impl,
+    attrs = {},
+    provides = [CcToolchainConfigInfo],
+)
+
+
diff --git a/toolchain/repo.bzl b/toolchain/repo.bzl
new file mode 100644
index 0000000..0d2b537
--- /dev/null
+++ b/toolchain/repo.bzl
@@ -0,0 +1,17 @@
+load("@bazel_tools//tools/build_defs/repo:utils.bzl", "maybe")
+load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
+
+def crt_repos(local = None):
+    if local:
+        native.local_repository(
+            name = "crt",
+            path = local,
+        )
+    else:
+        maybe(
+            http_archive,
+            name = "crt",
+            url = "https://github.com/lowRISC/crt/archive/refs/tags/v0.3.4.tar.gz",
+            sha256 = "01a66778d1a0d5bbfb4ba30e72bd6876d0c20766d0b1921ab36ca3350cb48c60",
+            strip_prefix = "crt-0.3.4",
+        )
\ No newline at end of file