summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_target/src/asm/riscv.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_target/src/asm/riscv.rs')
-rw-r--r--compiler/rustc_target/src/asm/riscv.rs185
1 files changed, 185 insertions, 0 deletions
diff --git a/compiler/rustc_target/src/asm/riscv.rs b/compiler/rustc_target/src/asm/riscv.rs
new file mode 100644
index 000000000..e41bdc9a5
--- /dev/null
+++ b/compiler/rustc_target/src/asm/riscv.rs
@@ -0,0 +1,185 @@
+use super::{InlineAsmArch, InlineAsmType};
+use crate::spec::{RelocModel, Target};
+use rustc_data_structures::fx::FxHashSet;
+use rustc_macros::HashStable_Generic;
+use rustc_span::{sym, Symbol};
+use std::fmt;
+
+def_reg_class! {
+ RiscV RiscVInlineAsmRegClass {
+ reg,
+ freg,
+ vreg,
+ }
+}
+
+impl RiscVInlineAsmRegClass {
+ 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 => {
+ if arch == InlineAsmArch::RiscV64 {
+ types! { _: I8, I16, I32, I64, F32, F64; }
+ } else {
+ types! { _: I8, I16, I32, F32; }
+ }
+ }
+ Self::freg => types! { f: F32; d: F64; },
+ Self::vreg => &[],
+ }
+ }
+}
+
+fn not_e(
+ _arch: InlineAsmArch,
+ _reloc_model: RelocModel,
+ target_features: &FxHashSet<Symbol>,
+ _target: &Target,
+ _is_clobber: bool,
+) -> Result<(), &'static str> {
+ if target_features.contains(&sym::e) {
+ Err("register can't be used with the `e` target feature")
+ } else {
+ Ok(())
+ }
+}
+
+def_regs! {
+ RiscV RiscVInlineAsmReg RiscVInlineAsmRegClass {
+ x1: reg = ["x1", "ra"],
+ x5: reg = ["x5", "t0"],
+ x6: reg = ["x6", "t1"],
+ x7: reg = ["x7", "t2"],
+ x10: reg = ["x10", "a0"],
+ x11: reg = ["x11", "a1"],
+ x12: reg = ["x12", "a2"],
+ x13: reg = ["x13", "a3"],
+ x14: reg = ["x14", "a4"],
+ x15: reg = ["x15", "a5"],
+ x16: reg = ["x16", "a6"] % not_e,
+ x17: reg = ["x17", "a7"] % not_e,
+ x18: reg = ["x18", "s2"] % not_e,
+ x19: reg = ["x19", "s3"] % not_e,
+ x20: reg = ["x20", "s4"] % not_e,
+ x21: reg = ["x21", "s5"] % not_e,
+ x22: reg = ["x22", "s6"] % not_e,
+ x23: reg = ["x23", "s7"] % not_e,
+ x24: reg = ["x24", "s8"] % not_e,
+ x25: reg = ["x25", "s9"] % not_e,
+ x26: reg = ["x26", "s10"] % not_e,
+ x27: reg = ["x27", "s11"] % not_e,
+ x28: reg = ["x28", "t3"] % not_e,
+ x29: reg = ["x29", "t4"] % not_e,
+ x30: reg = ["x30", "t5"] % not_e,
+ x31: reg = ["x31", "t6"] % not_e,
+ f0: freg = ["f0", "ft0"],
+ f1: freg = ["f1", "ft1"],
+ f2: freg = ["f2", "ft2"],
+ f3: freg = ["f3", "ft3"],
+ f4: freg = ["f4", "ft4"],
+ f5: freg = ["f5", "ft5"],
+ f6: freg = ["f6", "ft6"],
+ f7: freg = ["f7", "ft7"],
+ f8: freg = ["f8", "fs0"],
+ f9: freg = ["f9", "fs1"],
+ f10: freg = ["f10", "fa0"],
+ f11: freg = ["f11", "fa1"],
+ f12: freg = ["f12", "fa2"],
+ f13: freg = ["f13", "fa3"],
+ f14: freg = ["f14", "fa4"],
+ f15: freg = ["f15", "fa5"],
+ f16: freg = ["f16", "fa6"],
+ f17: freg = ["f17", "fa7"],
+ f18: freg = ["f18", "fs2"],
+ f19: freg = ["f19", "fs3"],
+ f20: freg = ["f20", "fs4"],
+ f21: freg = ["f21", "fs5"],
+ f22: freg = ["f22", "fs6"],
+ f23: freg = ["f23", "fs7"],
+ f24: freg = ["f24", "fs8"],
+ f25: freg = ["f25", "fs9"],
+ f26: freg = ["f26", "fs10"],
+ f27: freg = ["f27", "fs11"],
+ f28: freg = ["f28", "ft8"],
+ f29: freg = ["f29", "ft9"],
+ f30: freg = ["f30", "ft10"],
+ f31: freg = ["f31", "ft11"],
+ v0: vreg = ["v0"],
+ v1: vreg = ["v1"],
+ v2: vreg = ["v2"],
+ v3: vreg = ["v3"],
+ v4: vreg = ["v4"],
+ v5: vreg = ["v5"],
+ v6: vreg = ["v6"],
+ v7: vreg = ["v7"],
+ v8: vreg = ["v8"],
+ v9: vreg = ["v9"],
+ v10: vreg = ["v10"],
+ v11: vreg = ["v11"],
+ v12: vreg = ["v12"],
+ v13: vreg = ["v13"],
+ v14: vreg = ["v14"],
+ v15: vreg = ["v15"],
+ v16: vreg = ["v16"],
+ v17: vreg = ["v17"],
+ v18: vreg = ["v18"],
+ v19: vreg = ["v19"],
+ v20: vreg = ["v20"],
+ v21: vreg = ["v21"],
+ v22: vreg = ["v22"],
+ v23: vreg = ["v23"],
+ v24: vreg = ["v24"],
+ v25: vreg = ["v25"],
+ v26: vreg = ["v26"],
+ v27: vreg = ["v27"],
+ v28: vreg = ["v28"],
+ v29: vreg = ["v29"],
+ v30: vreg = ["v30"],
+ v31: vreg = ["v31"],
+ #error = ["x9", "s1"] =>
+ "s1 is used internally by LLVM and cannot be used as an operand for inline asm",
+ #error = ["x8", "s0", "fp"] =>
+ "the frame pointer cannot be used as an operand for inline asm",
+ #error = ["x2", "sp"] =>
+ "the stack pointer cannot be used as an operand for inline asm",
+ #error = ["x3", "gp"] =>
+ "the global pointer cannot be used as an operand for inline asm",
+ #error = ["x4", "tp"] =>
+ "the thread pointer cannot be used as an operand for inline asm" ,
+ #error = ["x0", "zero"] =>
+ "the zero register cannot be used as an operand for inline asm",
+ }
+}
+
+impl RiscVInlineAsmReg {
+ pub fn emit(
+ self,
+ out: &mut dyn fmt::Write,
+ _arch: InlineAsmArch,
+ _modifier: Option<char>,
+ ) -> fmt::Result {
+ out.write_str(self.name())
+ }
+}