about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
authorGus Caplan <me@gus.host>2020-11-02 14:59:45 -0600
committerGus Caplan <me@gus.host>2020-12-01 12:18:21 -0600
commitd9f237caa6a90fd6581124a3627af55e9c2a0f22 (patch)
tree6e30789de9d739fb7387b88ebc093a6c764253e0 /compiler
parent8a929386588be941659f4b6f454d200253b2eadc (diff)
downloadrust-d9f237caa6a90fd6581124a3627af55e9c2a0f22.tar.gz
rust-d9f237caa6a90fd6581124a3627af55e9c2a0f22.zip
Add wasm32 support to inline asm
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_codegen_llvm/src/asm.rs4
-rw-r--r--compiler/rustc_llvm/src/lib.rs3
-rw-r--r--compiler/rustc_target/src/asm/mod.rs21
-rw-r--r--compiler/rustc_target/src/asm/wasm.rs46
4 files changed, 73 insertions, 1 deletions
diff --git a/compiler/rustc_codegen_llvm/src/asm.rs b/compiler/rustc_codegen_llvm/src/asm.rs
index b5d279eeb6f..8801211d51b 100644
--- a/compiler/rustc_codegen_llvm/src/asm.rs
+++ b/compiler/rustc_codegen_llvm/src/asm.rs
@@ -261,6 +261,7 @@ impl AsmBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> {
                 InlineAsmArch::Hexagon => {}
                 InlineAsmArch::Mips | InlineAsmArch::Mips64 => {}
                 InlineAsmArch::SpirV => {}
+                InlineAsmArch::Wasm32 => {}
             }
         }
         if !options.contains(InlineAsmOptions::NOMEM) {
@@ -519,6 +520,7 @@ fn reg_to_llvm(reg: InlineAsmRegOrRegClass, layout: Option<&TyAndLayout<'tcx>>)
             | InlineAsmRegClass::X86(X86InlineAsmRegClass::ymm_reg) => "x",
             InlineAsmRegClass::X86(X86InlineAsmRegClass::zmm_reg) => "v",
             InlineAsmRegClass::X86(X86InlineAsmRegClass::kreg) => "^Yk",
+            InlineAsmRegClass::Wasm(WasmInlineAsmRegClass::local) => "r",
             InlineAsmRegClass::SpirV(SpirVInlineAsmRegClass::reg) => {
                 bug!("LLVM backend does not support SPIR-V")
             }
@@ -584,6 +586,7 @@ fn modifier_to_llvm(
             _ => unreachable!(),
         },
         InlineAsmRegClass::X86(X86InlineAsmRegClass::kreg) => None,
+        InlineAsmRegClass::Wasm(WasmInlineAsmRegClass::local) => None,
         InlineAsmRegClass::SpirV(SpirVInlineAsmRegClass::reg) => {
             bug!("LLVM backend does not support SPIR-V")
         }
@@ -626,6 +629,7 @@ fn dummy_output_type(cx: &CodegenCx<'ll, 'tcx>, reg: InlineAsmRegClass) -> &'ll
         | InlineAsmRegClass::X86(X86InlineAsmRegClass::ymm_reg)
         | InlineAsmRegClass::X86(X86InlineAsmRegClass::zmm_reg) => cx.type_f32(),
         InlineAsmRegClass::X86(X86InlineAsmRegClass::kreg) => cx.type_i16(),
+        InlineAsmRegClass::Wasm(WasmInlineAsmRegClass::local) => cx.type_i32(),
         InlineAsmRegClass::SpirV(SpirVInlineAsmRegClass::reg) => {
             bug!("LLVM backend does not support SPIR-V")
         }
diff --git a/compiler/rustc_llvm/src/lib.rs b/compiler/rustc_llvm/src/lib.rs
index a381290d46f..b2ffa271f62 100644
--- a/compiler/rustc_llvm/src/lib.rs
+++ b/compiler/rustc_llvm/src/lib.rs
@@ -167,6 +167,7 @@ pub fn initialize_available_targets() {
         LLVMInitializeWebAssemblyTargetInfo,
         LLVMInitializeWebAssemblyTarget,
         LLVMInitializeWebAssemblyTargetMC,
-        LLVMInitializeWebAssemblyAsmPrinter
+        LLVMInitializeWebAssemblyAsmPrinter,
+        LLVMInitializeWebAssemblyAsmParser
     );
 }
diff --git a/compiler/rustc_target/src/asm/mod.rs b/compiler/rustc_target/src/asm/mod.rs
index 5ebd6c4a234..aff1ff92d31 100644
--- a/compiler/rustc_target/src/asm/mod.rs
+++ b/compiler/rustc_target/src/asm/mod.rs
@@ -156,6 +156,7 @@ mod mips;
 mod nvptx;
 mod riscv;
 mod spirv;
+mod wasm;
 mod x86;
 
 pub use aarch64::{AArch64InlineAsmReg, AArch64InlineAsmRegClass};
@@ -165,6 +166,7 @@ pub use mips::{MipsInlineAsmReg, MipsInlineAsmRegClass};
 pub use nvptx::{NvptxInlineAsmReg, NvptxInlineAsmRegClass};
 pub use riscv::{RiscVInlineAsmReg, RiscVInlineAsmRegClass};
 pub use spirv::{SpirVInlineAsmReg, SpirVInlineAsmRegClass};
+pub use wasm::{WasmInlineAsmReg, WasmInlineAsmRegClass};
 pub use x86::{X86InlineAsmReg, X86InlineAsmRegClass};
 
 #[derive(Copy, Clone, Encodable, Decodable, Debug, Eq, PartialEq, Hash)]
@@ -180,6 +182,7 @@ pub enum InlineAsmArch {
     Mips,
     Mips64,
     SpirV,
+    Wasm32,
 }
 
 impl FromStr for InlineAsmArch {
@@ -198,6 +201,7 @@ impl FromStr for InlineAsmArch {
             "mips" => Ok(Self::Mips),
             "mips64" => Ok(Self::Mips64),
             "spirv" => Ok(Self::SpirV),
+            "wasm32" => Ok(Self::Wasm32),
             _ => Err(()),
         }
     }
@@ -213,6 +217,7 @@ pub enum InlineAsmReg {
     Hexagon(HexagonInlineAsmReg),
     Mips(MipsInlineAsmReg),
     SpirV(SpirVInlineAsmReg),
+    Wasm(WasmInlineAsmReg),
 }
 
 impl InlineAsmReg {
@@ -272,6 +277,9 @@ impl InlineAsmReg {
             InlineAsmArch::SpirV => {
                 Self::SpirV(SpirVInlineAsmReg::parse(arch, has_feature, target, &name)?)
             }
+            InlineAsmArch::Wasm32 => {
+                Self::Wasm(WasmInlineAsmReg::parse(arch, has_feature, target, &name)?)
+            }
         })
     }
 
@@ -315,6 +323,7 @@ pub enum InlineAsmRegClass {
     Hexagon(HexagonInlineAsmRegClass),
     Mips(MipsInlineAsmRegClass),
     SpirV(SpirVInlineAsmRegClass),
+    Wasm(WasmInlineAsmRegClass),
 }
 
 impl InlineAsmRegClass {
@@ -328,6 +337,7 @@ impl InlineAsmRegClass {
             Self::Hexagon(r) => r.name(),
             Self::Mips(r) => r.name(),
             Self::SpirV(r) => r.name(),
+            Self::Wasm(r) => r.name(),
         }
     }
 
@@ -344,6 +354,7 @@ impl InlineAsmRegClass {
             Self::Hexagon(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::Hexagon),
             Self::Mips(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::Mips),
             Self::SpirV(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::SpirV),
+            Self::Wasm(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::Wasm),
         }
     }
 
@@ -367,6 +378,7 @@ impl InlineAsmRegClass {
             Self::Hexagon(r) => r.suggest_modifier(arch, ty),
             Self::Mips(r) => r.suggest_modifier(arch, ty),
             Self::SpirV(r) => r.suggest_modifier(arch, ty),
+            Self::Wasm(r) => r.suggest_modifier(arch, ty),
         }
     }
 
@@ -386,6 +398,7 @@ impl InlineAsmRegClass {
             Self::Hexagon(r) => r.default_modifier(arch),
             Self::Mips(r) => r.default_modifier(arch),
             Self::SpirV(r) => r.default_modifier(arch),
+            Self::Wasm(r) => r.default_modifier(arch),
         }
     }
 
@@ -404,6 +417,7 @@ impl InlineAsmRegClass {
             Self::Hexagon(r) => r.supported_types(arch),
             Self::Mips(r) => r.supported_types(arch),
             Self::SpirV(r) => r.supported_types(arch),
+            Self::Wasm(r) => r.supported_types(arch),
         }
     }
 
@@ -429,6 +443,7 @@ impl InlineAsmRegClass {
                     Self::Mips(MipsInlineAsmRegClass::parse(arch, name)?)
                 }
                 InlineAsmArch::SpirV => Self::SpirV(SpirVInlineAsmRegClass::parse(arch, name)?),
+                InlineAsmArch::Wasm32 => Self::Wasm(WasmInlineAsmRegClass::parse(arch, name)?),
             })
         })
     }
@@ -445,6 +460,7 @@ impl InlineAsmRegClass {
             Self::Hexagon(r) => r.valid_modifiers(arch),
             Self::Mips(r) => r.valid_modifiers(arch),
             Self::SpirV(r) => r.valid_modifiers(arch),
+            Self::Wasm(r) => r.valid_modifiers(arch),
         }
     }
 }
@@ -592,5 +608,10 @@ pub fn allocatable_registers(
             spirv::fill_reg_map(arch, has_feature, target, &mut map);
             map
         }
+        InlineAsmArch::Wasm32 => {
+            let mut map = wasm::regclass_map();
+            wasm::fill_reg_map(arch, has_feature, target, &mut map);
+            map
+        }
     }
 }
diff --git a/compiler/rustc_target/src/asm/wasm.rs b/compiler/rustc_target/src/asm/wasm.rs
new file mode 100644
index 00000000000..1b33f8f9632
--- /dev/null
+++ b/compiler/rustc_target/src/asm/wasm.rs
@@ -0,0 +1,46 @@
+use super::{InlineAsmArch, InlineAsmType};
+use rustc_macros::HashStable_Generic;
+
+def_reg_class! {
+    Wasm WasmInlineAsmRegClass {
+        local,
+    }
+}
+
+impl WasmInlineAsmRegClass {
+    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<&'static str>)] {
+        match self {
+            Self::local => {
+                types! { _: I8, I16, I32, I64, F32, F64; }
+            }
+        }
+    }
+}
+
+def_regs! {
+    // WebAssembly doesn't have registers.
+    Wasm WasmInlineAsmReg WasmInlineAsmRegClass {}
+}