about summary refs log tree commit diff
path: root/compiler/rustc_target/src
diff options
context:
space:
mode:
authorDirreke <mingyang_ge@163.com>2023-07-13 22:19:59 +0800
committerdirreke <mingyang_ge@163.com>2023-08-14 23:02:36 +0800
commitd16409fe228f07c8a702ace7b42c1e1196ff85e6 (patch)
tree3e8ff9bcf8ce8a8cccd58511150bc24adff55301 /compiler/rustc_target/src
parent3071e0aef6dfd0a150c3fb1da0abad4ec86ca0aa (diff)
downloadrust-d16409fe228f07c8a702ace7b42c1e1196ff85e6.tar.gz
rust-d16409fe228f07c8a702ace7b42c1e1196ff85e6.zip
add a csky-unknown-linux-gnuabiv2 target
Diffstat (limited to 'compiler/rustc_target/src')
-rw-r--r--compiler/rustc_target/src/abi/call/csky.rs31
-rw-r--r--compiler/rustc_target/src/abi/call/mod.rs2
-rw-r--r--compiler/rustc_target/src/asm/csky.rs142
-rw-r--r--compiler/rustc_target/src/asm/mod.rs24
-rw-r--r--compiler/rustc_target/src/spec/csky_unknown_linux_gnuabiv2.rs22
-rw-r--r--compiler/rustc_target/src/spec/mod.rs1
6 files changed, 222 insertions, 0 deletions
diff --git a/compiler/rustc_target/src/abi/call/csky.rs b/compiler/rustc_target/src/abi/call/csky.rs
new file mode 100644
index 00000000000..75b453daa4f
--- /dev/null
+++ b/compiler/rustc_target/src/abi/call/csky.rs
@@ -0,0 +1,31 @@
+//see https://github.com/llvm/llvm-project/blob/main/llvm/lib/Target/CSKY/CSKYCallingConv.td
+use crate::abi::call::{ArgAbi, FnAbi};
+
+fn classify_ret<Ty>(ret: &mut ArgAbi<'_, Ty>) {
+    if ret.layout.is_aggregate() || ret.layout.size.bits() > 64 {
+        ret.make_indirect();
+    } else {
+        ret.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();
+    } else {
+        arg.extend_integer_width_to(32);
+    }
+}
+
+pub fn compute_abi_info<Ty>(fn_abi: &mut FnAbi<'_, Ty>) {
+    if !fn_abi.ret.is_ignore() {
+        classify_ret(&mut fn_abi.ret);
+    }
+
+    for arg in fn_abi.args.iter_mut() {
+        if arg.is_ignore() {
+            continue;
+        }
+        classify_arg(arg);
+    }
+}
diff --git a/compiler/rustc_target/src/abi/call/mod.rs b/compiler/rustc_target/src/abi/call/mod.rs
index e4989bdfbcd..8fab13d5d5d 100644
--- a/compiler/rustc_target/src/abi/call/mod.rs
+++ b/compiler/rustc_target/src/abi/call/mod.rs
@@ -9,6 +9,7 @@ mod amdgpu;
 mod arm;
 mod avr;
 mod bpf;
+mod csky;
 mod hexagon;
 mod loongarch;
 mod m68k;
@@ -712,6 +713,7 @@ impl<'a, Ty> FnAbi<'a, Ty> {
             "avr" => avr::compute_abi_info(self),
             "loongarch64" => loongarch::compute_abi_info(cx, self),
             "m68k" => m68k::compute_abi_info(self),
+            "csky" => csky::compute_abi_info(self),
             "mips" | "mips32r6" => mips::compute_abi_info(cx, self),
             "mips64" | "mips64r6" => mips64::compute_abi_info(cx, self),
             "powerpc" => powerpc::compute_abi_info(self),
diff --git a/compiler/rustc_target/src/asm/csky.rs b/compiler/rustc_target/src/asm/csky.rs
new file mode 100644
index 00000000000..13bb846c731
--- /dev/null
+++ b/compiler/rustc_target/src/asm/csky.rs
@@ -0,0 +1,142 @@
+use super::{InlineAsmArch, InlineAsmType};
+use rustc_macros::HashStable_Generic;
+use rustc_span::Symbol;
+use std::fmt;
+
+def_reg_class! {
+    CSKY CSKYInlineAsmRegClass {
+        reg,
+        freg,
+    }
+}
+
+impl CSKYInlineAsmRegClass {
+    pub fn valid_modifiers(self, _arch: super::InlineAsmArch) -> &'static [char] {
+        &[]
+    }
+
+    pub fn suggest_class(self, _arch: InlineAsmArch, _ty: InlineAsmType) -> Option<Self> {
+        None
+    }
+
+    pub fn suggest_modifier(
+        self,
+        _arch: InlineAsmArch,
+        _ty: InlineAsmType,
+    ) -> Option<(char, &'static str)> {
+        None
+    }
+
+    pub fn default_modifier(self, _arch: InlineAsmArch) -> Option<(char, &'static str)> {
+        None
+    }
+
+    pub fn supported_types(
+        self,
+        _arch: InlineAsmArch,
+    ) -> &'static [(InlineAsmType, Option<Symbol>)] {
+        match self {
+            Self::reg => types! { _: I8, I16, I32, I64, F32, F64; },
+            Self::freg => types! { _: F32, F64; },
+        }
+    }
+}
+
+// The reserved registers are taken from <https://github.com/llvm/llvm-project/blob/main/llvm/lib/Target/CSKY/CSKYRegisterInfo.cpp#79>
+def_regs! {
+    CSKY CSKYInlineAsmReg CSKYInlineAsmRegClass {
+        r0: reg = ["r0","a0"],
+        r1: reg = ["r1","a1"],
+        r2: reg = ["r2","a2"],
+        r3: reg = ["r3","a3"],
+        r4: reg = ["r4","l0"],
+        r5: reg = ["r5","l1"],
+        r6: reg = ["r6","l2"],
+        // r7: reg = ["r7","l3"],
+        // r8: reg = ["r8","l4"],
+        // r9: reg = ["r9","l5"],
+        // r10: reg = ["r10","l6"],
+        // r11: reg = ["r11","l7"],
+        // r12: reg = ["r12","t0"],
+        // r13: reg = ["r13","t1"],
+        // r14: reg = ["r14","sp"],
+        // r15: reg = ["r15","lr"],
+        // r16: reg = ["r16","l8"],
+        // r17: reg = ["r17","l9"],
+        // r18: reg = ["r18","t2"],
+        // r19: reg = ["r19","t3"],
+        // r20: reg = ["r20","t4"],
+        // r21: reg = ["r21","t5"],
+        // r22: reg = ["r22","t6"],
+        // r23: reg = ["r23","t7", "fp"],
+        // r24: reg = ["r24","t8", "sop"],
+        // r25: reg = ["r25","tp", "bsp"],
+        // r26: reg = ["r26"],
+        // r27: reg = ["r27"],
+        // r28: reg = ["r28","gb", "rgb", "rdb"],
+        // r29: reg = ["r29","tb", "rtb"],
+        // r30: reg = ["r30","svbr"],
+        // r31: reg = ["r31","tls"],
+        f0: freg = ["fr0","vr0"],
+        f1: freg = ["fr1","vr1"],
+        f2: freg = ["fr2","vr2"],
+        f3: freg = ["fr3","vr3"],
+        f4: freg = ["fr4","vr4"],
+        f5: freg = ["fr5","vr5"],
+        f6: freg = ["fr6","vr6"],
+        f7: freg = ["fr7","vr7"],
+        f8: freg = ["fr8","vr8"],
+        f9: freg = ["fr9","vr9"],
+        f10: freg = ["fr10","vr10"],
+        f11: freg = ["fr11","vr11"],
+        f12: freg = ["fr12","vr12"],
+        f13: freg = ["fr13","vr13"],
+        f14: freg = ["fr14","vr14"],
+        f15: freg = ["fr15","vr15"],
+        f16: freg = ["fr16","vr16"],
+        f17: freg = ["fr17","vr17"],
+        f18: freg = ["fr18","vr18"],
+        f19: freg = ["fr19","vr19"],
+        f20: freg = ["fr20","vr20"],
+        f21: freg = ["fr21","vr21"],
+        f22: freg = ["fr22","vr22"],
+        f23: freg = ["fr23","vr23"],
+        f24: freg = ["fr24","vr24"],
+        f25: freg = ["fr25","vr25"],
+        f26: freg = ["fr26","vr26"],
+        f27: freg = ["fr27","vr27"],
+        f28: freg = ["fr28","vr28"],
+        f29: freg = ["fr29","vr29"],
+        f30: freg = ["fr30","vr30"],
+        f31: freg = ["fr31","vr31"],
+        #error = ["r7", "l3"] =>
+            "the base pointer cannot be used as an operand for inline asm",
+        #error = ["r8","l4"] =>
+            "the frame pointer cannot be used as an operand for inline asm",
+        #error = ["r14","sp"] =>
+            "the stack pointer cannot be used as an operand for inline asm",
+        #error = ["r15","lr"] =>
+            "the link register cannot be used as an operand for inline asm",
+        #error = ["r31","tls"] =>
+            "reserver for tls",
+        #error = ["r28", "gb", "rgb", "rdb"] =>
+            "the global pointer cannot be used as an operand for inline asm",
+        #error = ["r9","l5", "r10","l6", "r11","l7", "r12","t0", "r13","t1"] =>
+            "reserved (no E2)",
+        #error = ["r16","l8", "r17","l9", "r18","t2", "r19","t3", "r20","t4", "r21","t5", "r22","t6", "r23","t7", "fp", "r24","t8", "sop", "r25","tp", "bsp"] =>
+            "reserved (no HighRegisters)",
+        #error = ["r26","r27","r29","tb", "rtb", "r30","svbr"] =>
+            "reserved by the ABI",
+    }
+}
+
+impl CSKYInlineAsmReg {
+    pub fn emit(
+        self,
+        out: &mut dyn fmt::Write,
+        _arch: InlineAsmArch,
+        _modifier: Option<char>,
+    ) -> fmt::Result {
+        out.write_str(self.name())
+    }
+}
diff --git a/compiler/rustc_target/src/asm/mod.rs b/compiler/rustc_target/src/asm/mod.rs
index 7c27732079b..a11884bea26 100644
--- a/compiler/rustc_target/src/asm/mod.rs
+++ b/compiler/rustc_target/src/asm/mod.rs
@@ -167,6 +167,7 @@ mod aarch64;
 mod arm;
 mod avr;
 mod bpf;
+mod csky;
 mod hexagon;
 mod loongarch;
 mod m68k;
@@ -184,6 +185,7 @@ pub use aarch64::{AArch64InlineAsmReg, AArch64InlineAsmRegClass};
 pub use arm::{ArmInlineAsmReg, ArmInlineAsmRegClass};
 pub use avr::{AvrInlineAsmReg, AvrInlineAsmRegClass};
 pub use bpf::{BpfInlineAsmReg, BpfInlineAsmRegClass};
+pub use csky::{CSKYInlineAsmReg, CSKYInlineAsmRegClass};
 pub use hexagon::{HexagonInlineAsmReg, HexagonInlineAsmRegClass};
 pub use loongarch::{LoongArchInlineAsmReg, LoongArchInlineAsmRegClass};
 pub use m68k::{M68kInlineAsmReg, M68kInlineAsmRegClass};
@@ -220,6 +222,7 @@ pub enum InlineAsmArch {
     Avr,
     Msp430,
     M68k,
+    CSKY,
 }
 
 impl FromStr for InlineAsmArch {
@@ -248,6 +251,7 @@ impl FromStr for InlineAsmArch {
             "avr" => Ok(Self::Avr),
             "msp430" => Ok(Self::Msp430),
             "m68k" => Ok(Self::M68k),
+            "csky" => Ok(Self::CSKY),
             _ => Err(()),
         }
     }
@@ -272,6 +276,7 @@ pub enum InlineAsmReg {
     Avr(AvrInlineAsmReg),
     Msp430(Msp430InlineAsmReg),
     M68k(M68kInlineAsmReg),
+    CSKY(CSKYInlineAsmReg),
     // Placeholder for invalid register constraints for the current target
     Err,
 }
@@ -292,6 +297,7 @@ impl InlineAsmReg {
             Self::Avr(r) => r.name(),
             Self::Msp430(r) => r.name(),
             Self::M68k(r) => r.name(),
+            Self::CSKY(r) => r.name(),
             Self::Err => "<reg>",
         }
     }
@@ -311,6 +317,7 @@ impl InlineAsmReg {
             Self::Avr(r) => InlineAsmRegClass::Avr(r.reg_class()),
             Self::Msp430(r) => InlineAsmRegClass::Msp430(r.reg_class()),
             Self::M68k(r) => InlineAsmRegClass::M68k(r.reg_class()),
+            Self::CSKY(r) => InlineAsmRegClass::CSKY(r.reg_class()),
             Self::Err => InlineAsmRegClass::Err,
         }
     }
@@ -344,6 +351,7 @@ impl InlineAsmReg {
             InlineAsmArch::Avr => Self::Avr(AvrInlineAsmReg::parse(name)?),
             InlineAsmArch::Msp430 => Self::Msp430(Msp430InlineAsmReg::parse(name)?),
             InlineAsmArch::M68k => Self::M68k(M68kInlineAsmReg::parse(name)?),
+            InlineAsmArch::CSKY => Self::CSKY(CSKYInlineAsmReg::parse(name)?),
         })
     }
 
@@ -371,6 +379,7 @@ impl InlineAsmReg {
             Self::Avr(r) => r.validate(arch, reloc_model, target_features, target, is_clobber),
             Self::Msp430(r) => r.validate(arch, reloc_model, target_features, target, is_clobber),
             Self::M68k(r) => r.validate(arch, reloc_model, target_features, target, is_clobber),
+            Self::CSKY(r) => r.validate(arch, reloc_model, target_features, target, is_clobber),
             Self::Err => unreachable!(),
         }
     }
@@ -397,6 +406,7 @@ impl InlineAsmReg {
             Self::Avr(r) => r.emit(out, arch, modifier),
             Self::Msp430(r) => r.emit(out, arch, modifier),
             Self::M68k(r) => r.emit(out, arch, modifier),
+            Self::CSKY(r) => r.emit(out, arch, modifier),
             Self::Err => unreachable!("Use of InlineAsmReg::Err"),
         }
     }
@@ -416,6 +426,7 @@ impl InlineAsmReg {
             Self::Avr(r) => r.overlapping_regs(|r| cb(Self::Avr(r))),
             Self::Msp430(_) => cb(self),
             Self::M68k(_) => cb(self),
+            Self::CSKY(_) => cb(self),
             Self::Err => unreachable!("Use of InlineAsmReg::Err"),
         }
     }
@@ -440,6 +451,7 @@ pub enum InlineAsmRegClass {
     Avr(AvrInlineAsmRegClass),
     Msp430(Msp430InlineAsmRegClass),
     M68k(M68kInlineAsmRegClass),
+    CSKY(CSKYInlineAsmRegClass),
     // Placeholder for invalid register constraints for the current target
     Err,
 }
@@ -463,6 +475,7 @@ impl InlineAsmRegClass {
             Self::Avr(r) => r.name(),
             Self::Msp430(r) => r.name(),
             Self::M68k(r) => r.name(),
+            Self::CSKY(r) => r.name(),
             Self::Err => rustc_span::symbol::sym::reg,
         }
     }
@@ -488,6 +501,7 @@ impl InlineAsmRegClass {
             Self::Avr(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::Avr),
             Self::Msp430(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::Msp430),
             Self::M68k(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::M68k),
+            Self::CSKY(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::CSKY),
             Self::Err => unreachable!("Use of InlineAsmRegClass::Err"),
         }
     }
@@ -520,6 +534,7 @@ impl InlineAsmRegClass {
             Self::Avr(r) => r.suggest_modifier(arch, ty),
             Self::Msp430(r) => r.suggest_modifier(arch, ty),
             Self::M68k(r) => r.suggest_modifier(arch, ty),
+            Self::CSKY(r) => r.suggest_modifier(arch, ty),
             Self::Err => unreachable!("Use of InlineAsmRegClass::Err"),
         }
     }
@@ -548,6 +563,7 @@ impl InlineAsmRegClass {
             Self::Avr(r) => r.default_modifier(arch),
             Self::Msp430(r) => r.default_modifier(arch),
             Self::M68k(r) => r.default_modifier(arch),
+            Self::CSKY(r) => r.default_modifier(arch),
             Self::Err => unreachable!("Use of InlineAsmRegClass::Err"),
         }
     }
@@ -575,6 +591,7 @@ impl InlineAsmRegClass {
             Self::Avr(r) => r.supported_types(arch),
             Self::Msp430(r) => r.supported_types(arch),
             Self::M68k(r) => r.supported_types(arch),
+            Self::CSKY(r) => r.supported_types(arch),
             Self::Err => unreachable!("Use of InlineAsmRegClass::Err"),
         }
     }
@@ -607,6 +624,7 @@ impl InlineAsmRegClass {
             InlineAsmArch::Avr => Self::Avr(AvrInlineAsmRegClass::parse(name)?),
             InlineAsmArch::Msp430 => Self::Msp430(Msp430InlineAsmRegClass::parse(name)?),
             InlineAsmArch::M68k => Self::M68k(M68kInlineAsmRegClass::parse(name)?),
+            InlineAsmArch::CSKY => Self::CSKY(CSKYInlineAsmRegClass::parse(name)?),
         })
     }
 
@@ -630,6 +648,7 @@ impl InlineAsmRegClass {
             Self::Avr(r) => r.valid_modifiers(arch),
             Self::Msp430(r) => r.valid_modifiers(arch),
             Self::M68k(r) => r.valid_modifiers(arch),
+            Self::CSKY(r) => r.valid_modifiers(arch),
             Self::Err => unreachable!("Use of InlineAsmRegClass::Err"),
         }
     }
@@ -826,6 +845,11 @@ pub fn allocatable_registers(
             m68k::fill_reg_map(arch, reloc_model, target_features, target, &mut map);
             map
         }
+        InlineAsmArch::CSKY => {
+            let mut map = csky::regclass_map();
+            csky::fill_reg_map(arch, reloc_model, target_features, target, &mut map);
+            map
+        }
     }
 }
 
diff --git a/compiler/rustc_target/src/spec/csky_unknown_linux_gnuabiv2.rs b/compiler/rustc_target/src/spec/csky_unknown_linux_gnuabiv2.rs
new file mode 100644
index 00000000000..181cad0163a
--- /dev/null
+++ b/compiler/rustc_target/src/spec/csky_unknown_linux_gnuabiv2.rs
@@ -0,0 +1,22 @@
+use crate::spec::{Target, TargetOptions};
+
+// This target is for glibc Linux on Csky
+// hardfloat.
+
+pub fn target() -> Target {
+    Target {
+        //https://github.com/llvm/llvm-project/blob/8b76aea8d8b1b71f6220bc2845abc749f18a19b7/clang/lib/Basic/Targets/CSKY.h
+        llvm_target: "csky-unknown-linux".into(),
+        pointer_width: 32,
+        data_layout: "e-m:e-S32-p:32:32-i32:32:32-i64:32:32-f32:32:32-f64:32:32-v64:32:32-v128:32:32-a:0:32-Fi32-n32".into(),
+        arch: "csky".into(),
+        options: TargetOptions {
+            abi: "abiv2".into(),
+            //+hard-float, +hard-float-abi, +fpuv2_sf, +fpuv2_df, +fpuv3_sf, +fpuv3_df,  +vdspv2, +dspv2, +vdspv1, +3e3r1
+            features: "".into(),
+            max_atomic_width: Some(32),
+            // mcount: "\u{1}__gnu_mcount_nc".into(),
+            ..super::linux_gnu_base::opts()
+        },
+    }
+}
diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs
index 1871239d7de..6ada4e49083 100644
--- a/compiler/rustc_target/src/spec/mod.rs
+++ b/compiler/rustc_target/src/spec/mod.rs
@@ -1246,6 +1246,7 @@ supported_targets! {
     ("i586-unknown-linux-gnu", i586_unknown_linux_gnu),
     ("loongarch64-unknown-linux-gnu", loongarch64_unknown_linux_gnu),
     ("m68k-unknown-linux-gnu", m68k_unknown_linux_gnu),
+    ("csky-unknown-linux-gnuabiv2", csky_unknown_linux_gnuabiv2),
     ("mips-unknown-linux-gnu", mips_unknown_linux_gnu),
     ("mips64-unknown-linux-gnuabi64", mips64_unknown_linux_gnuabi64),
     ("mips64el-unknown-linux-gnuabi64", mips64el_unknown_linux_gnuabi64),