about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_target/src/abi/call/csky.rs38
-rw-r--r--src/doc/rustc/src/platform-support/csky-unknown-linux-gnuabiv2.md10
2 files changed, 38 insertions, 10 deletions
diff --git a/compiler/rustc_target/src/abi/call/csky.rs b/compiler/rustc_target/src/abi/call/csky.rs
index bbe95fa20ac..706493b0a6a 100644
--- a/compiler/rustc_target/src/abi/call/csky.rs
+++ b/compiler/rustc_target/src/abi/call/csky.rs
@@ -1,17 +1,39 @@
-// See https://github.com/llvm/llvm-project/blob/d85b94bf0080dcd780656c0f5e6342800720eba9/llvm/lib/Target/CSKY/CSKYCallingConv.td
-use crate::abi::call::{ArgAbi, FnAbi};
+// Reference: CSKY ABI Manual
+// https://occ-oss-prod.oss-cn-hangzhou.aliyuncs.com/resource//1695027452256/T-HEAD_800_Series_ABI_Standards_Manual.pdf
+//
+// Reference: Clang CSKY lowering code
+// https://github.com/llvm/llvm-project/blob/4a074f32a6914f2a8d7215d78758c24942dddc3d/clang/lib/CodeGen/Targets/CSKY.cpp#L76-L162
 
-fn classify_ret<Ty>(ret: &mut ArgAbi<'_, Ty>) {
-    if ret.layout.is_aggregate() || ret.layout.size.bits() > 64 {
-        ret.make_indirect();
+use crate::abi::call::{ArgAbi, FnAbi, Reg, Uniform};
+
+fn classify_ret<Ty>(arg: &mut ArgAbi<'_, Ty>) {
+    // For return type, aggregate which <= 2*XLen will be returned in registers.
+    // Otherwise, aggregate will be returned indirectly.
+    if arg.layout.is_aggregate() {
+        let total = arg.layout.size;
+        if total.bits() > 64 {
+            arg.make_indirect();
+        } else if total.bits() > 32 {
+            arg.cast_to(Uniform { unit: Reg::i32(), total });
+        } else {
+            arg.cast_to(Reg::i32());
+        }
     } else {
-        ret.extend_integer_width_to(32);
+        arg.extend_integer_width_to(32);
     }
 }
 
 fn classify_arg<Ty>(arg: &mut ArgAbi<'_, Ty>) {
-    if arg.layout.is_aggregate() || arg.layout.size.bits() > 64 {
-        arg.make_indirect();
+    // For argument type, the first 4*XLen parts of aggregate will be passed
+    // in registers, and the rest will be passed in stack.
+    // So we can coerce to integers directly and let backend handle it correctly.
+    if arg.layout.is_aggregate() {
+        let total = arg.layout.size;
+        if total.bits() > 32 {
+            arg.cast_to(Uniform { unit: Reg::i32(), total });
+        } else {
+            arg.cast_to(Reg::i32());
+        }
     } else {
         arg.extend_integer_width_to(32);
     }
diff --git a/src/doc/rustc/src/platform-support/csky-unknown-linux-gnuabiv2.md b/src/doc/rustc/src/platform-support/csky-unknown-linux-gnuabiv2.md
index 57c717c182d..a54abcb606e 100644
--- a/src/doc/rustc/src/platform-support/csky-unknown-linux-gnuabiv2.md
+++ b/src/doc/rustc/src/platform-support/csky-unknown-linux-gnuabiv2.md
@@ -10,9 +10,15 @@ target | std | host | notes
 `csky-unknown-linux-gnuabiv2hf` | ✓ |  | C-SKY abiv2 Linux, hardfloat (little endian)
 
 Reference:
-https://c-sky.github.io/
 
-https://gitlab.com/c-sky/
+- [CSKY ABI Manual](https://occ-oss-prod.oss-cn-hangzhou.aliyuncs.com/resource//1695027452256/T-HEAD_800_Series_ABI_Standards_Manual.pdf)
+- [csky-linux-gnuabiv2-toolchain](https://occ-oss-prod.oss-cn-hangzhou.aliyuncs.com/resource/1356021/1619528643136/csky-linux-gnuabiv2-tools-x86_64-glibc-linux-4.9.56-20210423.tar.gz)
+- [csky-linux-gnuabiv2-qemu](https://occ-oss-prod.oss-cn-hangzhou.aliyuncs.com/resource//1689324918932/xuantie-qemu-x86_64-Ubuntu-18.04-20230714-0202.tar.gz)
+
+other links:
+
+- https://c-sky.github.io/
+- https://gitlab.com/c-sky/
 
 ## Target maintainers