Skip to content

Commit

Permalink
asm! support for the Xtensa architecture (#68)
Browse files Browse the repository at this point in the history
Co-authored-by: Taiki Endo <te316e89@gmail.com>
  • Loading branch information
MabezDev and taiki-e committed Nov 6, 2024
1 parent a582efa commit 8c0f82e
Show file tree
Hide file tree
Showing 6 changed files with 525 additions and 0 deletions.
8 changes: 8 additions & 0 deletions compiler/rustc_codegen_llvm/src/asm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,7 @@ impl<'ll, 'tcx> AsmBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
}
InlineAsmArch::SpirV => {}
InlineAsmArch::Wasm32 | InlineAsmArch::Wasm64 => {}
InlineAsmArch::Xtensa => {}
InlineAsmArch::Bpf => {}
InlineAsmArch::Msp430 => {
constraints.push("~{sr}".to_string());
Expand Down Expand Up @@ -701,6 +702,9 @@ fn reg_to_llvm(reg: InlineAsmRegOrRegClass, layout: Option<&TyAndLayout<'_>>) ->
| X86InlineAsmRegClass::tmm_reg,
) => unreachable!("clobber-only"),
InlineAsmRegClass::Wasm(WasmInlineAsmRegClass::local) => "r",
InlineAsmRegClass::Xtensa(XtensaInlineAsmRegClass::reg) => "r",
InlineAsmRegClass::Xtensa(XtensaInlineAsmRegClass::freg) => "f",
InlineAsmRegClass::Xtensa(XtensaInlineAsmRegClass::breg) => "b",
InlineAsmRegClass::Bpf(BpfInlineAsmRegClass::reg) => "r",
InlineAsmRegClass::Bpf(BpfInlineAsmRegClass::wreg) => "w",
InlineAsmRegClass::Avr(AvrInlineAsmRegClass::reg) => "r",
Expand Down Expand Up @@ -763,6 +767,7 @@ fn modifier_to_llvm(
InlineAsmRegClass::Mips(_) => None,
InlineAsmRegClass::Nvptx(_) => None,
InlineAsmRegClass::PowerPC(_) => None,
InlineAsmRegClass::Xtensa(_) => None,
InlineAsmRegClass::RiscV(RiscVInlineAsmRegClass::reg)
| InlineAsmRegClass::RiscV(RiscVInlineAsmRegClass::freg) => None,
InlineAsmRegClass::RiscV(RiscVInlineAsmRegClass::vreg) => {
Expand Down Expand Up @@ -880,6 +885,9 @@ fn dummy_output_type<'ll>(cx: &CodegenCx<'ll, '_>, reg: InlineAsmRegClass) -> &'
unreachable!("clobber-only")
}
InlineAsmRegClass::Wasm(WasmInlineAsmRegClass::local) => cx.type_i32(),
InlineAsmRegClass::Xtensa(XtensaInlineAsmRegClass::reg) => cx.type_i32(),
InlineAsmRegClass::Xtensa(XtensaInlineAsmRegClass::freg) => cx.type_f32(),
InlineAsmRegClass::Xtensa(XtensaInlineAsmRegClass::breg) => cx.type_i1(),
InlineAsmRegClass::Bpf(BpfInlineAsmRegClass::reg) => cx.type_i64(),
InlineAsmRegClass::Bpf(BpfInlineAsmRegClass::wreg) => cx.type_i32(),
InlineAsmRegClass::Avr(AvrInlineAsmRegClass::reg) => cx.type_i8(),
Expand Down
24 changes: 24 additions & 0 deletions compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -466,6 +466,7 @@ symbols! {
async_for_loop,
async_iterator,
async_iterator_poll_next,
atomctl,
atomic,
atomic_mod,
atomics,
Expand Down Expand Up @@ -507,6 +508,7 @@ symbols! {
braced_empty_structs,
branch,
breakpoint,
breg,
bridge,
bswap,
builtin_syntax,
Expand Down Expand Up @@ -641,6 +643,7 @@ symbols! {
constant,
constructor,
convert_identity,
coprocessor,
copy,
copy_closures,
copy_nonoverlapping,
Expand Down Expand Up @@ -731,6 +734,7 @@ symbols! {
derive_smart_pointer,
destruct,
destructuring_assignment,
dfpaccel,
diagnostic,
diagnostic_namespace,
direct,
Expand Down Expand Up @@ -794,6 +798,7 @@ symbols! {
ermsb_target_feature,
exact_div,
except,
exception,
exchange_malloc,
exclusive_range_pattern,
exhaustive_integer_patterns,
Expand All @@ -817,6 +822,7 @@ symbols! {
expr_fragment_specifier_2024,
extended_key_value_attributes,
extended_varargs_abi_support,
extendedl32r,
extern_absolute_paths,
extern_crate_item_prelude,
extern_crate_self,
Expand Down Expand Up @@ -921,6 +927,7 @@ symbols! {
format_macro,
format_placeholder,
format_unsafe_arg,
fp,
freeze,
freeze_impls,
freg,
Expand Down Expand Up @@ -972,6 +979,7 @@ symbols! {
hash,
hexagon_target_feature,
hidden,
highpriinterrupts,
homogeneous_aggregate,
host,
html_favicon_url,
Expand Down Expand Up @@ -1050,6 +1058,8 @@ symbols! {
instruction_set,
integer_: "integer", // underscore to avoid clashing with the function `sym::integer` below
integral,
intel,
interrupt,
into_async_iter_into_iter,
into_future,
into_iter,
Expand Down Expand Up @@ -1137,6 +1147,7 @@ symbols! {
loongarch_target_feature,
loop_break_value,
lt,
mac16,
macro_at_most_once_rep,
macro_attributes_in_derive_output,
macro_escape,
Expand Down Expand Up @@ -1180,6 +1191,7 @@ symbols! {
mem_variant_count,
mem_zeroed,
member_constraints,
memctl,
memory,
memtag,
message,
Expand Down Expand Up @@ -1234,6 +1246,8 @@ symbols! {
mir_unwind_unreachable,
mir_variant,
miri,
misc,
miscsr,
mmx_reg,
modifiers,
module,
Expand Down Expand Up @@ -1450,6 +1464,8 @@ symbols! {
prelude_import,
preserves_flags,
prfchw_target_feature,
prid,
primitive,
print_macro,
println_macro,
proc_dash_macro: "proc-macro",
Expand Down Expand Up @@ -1702,8 +1718,10 @@ symbols! {
rustdoc_missing_doc_code_examples,
rustfmt,
rvalue_static_promotion,
rvector,
rwpi,
s,
s32c1i,
s390x_target_feature,
safety,
sanitize,
Expand Down Expand Up @@ -1900,10 +1918,12 @@ symbols! {
thread,
thread_local,
thread_local_macro,
threadptr,
three_way_compare,
thumb2,
thumb_mode: "thumb-mode",
time,
timerint,
tmm_reg,
to_owned_method,
to_string,
Expand Down Expand Up @@ -2081,6 +2101,8 @@ symbols! {
wasm_import_module,
wasm_target_feature,
while_let,
width,
windowed,
windows,
windows_subsystem,
with_negative_coherence,
Expand All @@ -2099,8 +2121,10 @@ symbols! {
x86_amx_intrinsics,
x87_reg,
xer,
xloop,
xmm_reg,
xop_target_feature,
xtensa_target_feature,
yeet_desugar_details,
yeet_expr,
yes,
Expand Down
29 changes: 29 additions & 0 deletions compiler/rustc_target/src/asm/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,7 @@ mod s390x;
mod spirv;
mod wasm;
mod x86;
mod xtensa;

pub use aarch64::{AArch64InlineAsmReg, AArch64InlineAsmRegClass};
pub use arm::{ArmInlineAsmReg, ArmInlineAsmRegClass};
Expand All @@ -211,6 +212,7 @@ pub use riscv::{RiscVInlineAsmReg, RiscVInlineAsmRegClass};
pub use s390x::{S390xInlineAsmReg, S390xInlineAsmRegClass};
pub use spirv::{SpirVInlineAsmReg, SpirVInlineAsmRegClass};
pub use wasm::{WasmInlineAsmReg, WasmInlineAsmRegClass};
pub use xtensa::{XtensaInlineAsmReg, XtensaInlineAsmRegClass};
pub use x86::{X86InlineAsmReg, X86InlineAsmRegClass};

#[derive(Copy, Clone, Encodable, Decodable, Debug, Eq, PartialEq, Hash)]
Expand All @@ -233,6 +235,7 @@ pub enum InlineAsmArch {
SpirV,
Wasm32,
Wasm64,
Xtensa,
Bpf,
Avr,
Msp430,
Expand Down Expand Up @@ -263,6 +266,7 @@ impl FromStr for InlineAsmArch {
"spirv" => Ok(Self::SpirV),
"wasm32" => Ok(Self::Wasm32),
"wasm64" => Ok(Self::Wasm64),
"xtensa" => Ok(Self::Xtensa),
"bpf" => Ok(Self::Bpf),
"avr" => Ok(Self::Avr),
"msp430" => Ok(Self::Msp430),
Expand All @@ -288,6 +292,7 @@ pub enum InlineAsmReg {
S390x(S390xInlineAsmReg),
SpirV(SpirVInlineAsmReg),
Wasm(WasmInlineAsmReg),
Xtensa(XtensaInlineAsmReg),
Bpf(BpfInlineAsmReg),
Avr(AvrInlineAsmReg),
Msp430(Msp430InlineAsmReg),
Expand All @@ -309,6 +314,7 @@ impl InlineAsmReg {
Self::LoongArch(r) => r.name(),
Self::Mips(r) => r.name(),
Self::S390x(r) => r.name(),
Self::Xtensa(r) => r.name(),
Self::Bpf(r) => r.name(),
Self::Avr(r) => r.name(),
Self::Msp430(r) => r.name(),
Expand All @@ -329,6 +335,7 @@ impl InlineAsmReg {
Self::LoongArch(r) => InlineAsmRegClass::LoongArch(r.reg_class()),
Self::Mips(r) => InlineAsmRegClass::Mips(r.reg_class()),
Self::S390x(r) => InlineAsmRegClass::S390x(r.reg_class()),
Self::Xtensa(r) => InlineAsmRegClass::Xtensa(r.reg_class()),
Self::Bpf(r) => InlineAsmRegClass::Bpf(r.reg_class()),
Self::Avr(r) => InlineAsmRegClass::Avr(r.reg_class()),
Self::Msp430(r) => InlineAsmRegClass::Msp430(r.reg_class()),
Expand Down Expand Up @@ -360,6 +367,9 @@ impl InlineAsmReg {
InlineAsmArch::Mips | InlineAsmArch::Mips64 => {
Self::Mips(MipsInlineAsmReg::parse(name)?)
}
InlineAsmArch::Xtensa => {
Self::Xtensa(XtensaInlineAsmReg::parse(name)?)
}
InlineAsmArch::S390x => Self::S390x(S390xInlineAsmReg::parse(name)?),
InlineAsmArch::SpirV => Self::SpirV(SpirVInlineAsmReg::parse(name)?),
InlineAsmArch::Wasm32 | InlineAsmArch::Wasm64 => {
Expand Down Expand Up @@ -395,6 +405,7 @@ impl InlineAsmReg {
Self::S390x(r) => r.validate(arch, reloc_model, target_features, target, is_clobber),
Self::Bpf(r) => r.validate(arch, reloc_model, target_features, target, is_clobber),
Self::Avr(r) => r.validate(arch, reloc_model, target_features, target, is_clobber),
Self::Xtensa(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),
Expand All @@ -420,6 +431,7 @@ impl InlineAsmReg {
Self::LoongArch(r) => r.emit(out, arch, modifier),
Self::Mips(r) => r.emit(out, arch, modifier),
Self::S390x(r) => r.emit(out, arch, modifier),
Self::Xtensa(r) => r.emit(out, arch, modifier),
Self::Bpf(r) => r.emit(out, arch, modifier),
Self::Avr(r) => r.emit(out, arch, modifier),
Self::Msp430(r) => r.emit(out, arch, modifier),
Expand All @@ -440,6 +452,7 @@ impl InlineAsmReg {
Self::LoongArch(_) => cb(self),
Self::Mips(_) => cb(self),
Self::S390x(_) => cb(self),
Self::Xtensa(_) => cb(self),
Self::Bpf(r) => r.overlapping_regs(|r| cb(Self::Bpf(r))),
Self::Avr(r) => r.overlapping_regs(|r| cb(Self::Avr(r))),
Self::Msp430(_) => cb(self),
Expand All @@ -465,6 +478,7 @@ pub enum InlineAsmRegClass {
S390x(S390xInlineAsmRegClass),
SpirV(SpirVInlineAsmRegClass),
Wasm(WasmInlineAsmRegClass),
Xtensa(XtensaInlineAsmRegClass),
Bpf(BpfInlineAsmRegClass),
Avr(AvrInlineAsmRegClass),
Msp430(Msp430InlineAsmRegClass),
Expand All @@ -489,6 +503,7 @@ impl InlineAsmRegClass {
Self::S390x(r) => r.name(),
Self::SpirV(r) => r.name(),
Self::Wasm(r) => r.name(),
Self::Xtensa(r) => r.name(),
Self::Bpf(r) => r.name(),
Self::Avr(r) => r.name(),
Self::Msp430(r) => r.name(),
Expand All @@ -515,6 +530,7 @@ impl InlineAsmRegClass {
Self::S390x(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::S390x),
Self::SpirV(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::SpirV),
Self::Wasm(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::Wasm),
Self::Xtensa(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::Xtensa),
Self::Bpf(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::Bpf),
Self::Avr(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::Avr),
Self::Msp430(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::Msp430),
Expand Down Expand Up @@ -544,6 +560,7 @@ impl InlineAsmRegClass {
Self::S390x(r) => r.suggest_modifier(arch, ty),
Self::SpirV(r) => r.suggest_modifier(arch, ty),
Self::Wasm(r) => r.suggest_modifier(arch, ty),
Self::Xtensa(r) => r.suggest_modifier(arch, ty),
Self::Bpf(r) => r.suggest_modifier(arch, ty),
Self::Avr(r) => r.suggest_modifier(arch, ty),
Self::Msp430(r) => r.suggest_modifier(arch, ty),
Expand Down Expand Up @@ -573,6 +590,7 @@ impl InlineAsmRegClass {
Self::S390x(r) => r.default_modifier(arch),
Self::SpirV(r) => r.default_modifier(arch),
Self::Wasm(r) => r.default_modifier(arch),
Self::Xtensa(r) => r.default_modifier(arch),
Self::Bpf(r) => r.default_modifier(arch),
Self::Avr(r) => r.default_modifier(arch),
Self::Msp430(r) => r.default_modifier(arch),
Expand Down Expand Up @@ -601,6 +619,7 @@ impl InlineAsmRegClass {
Self::S390x(r) => r.supported_types(arch),
Self::SpirV(r) => r.supported_types(arch),
Self::Wasm(r) => r.supported_types(arch),
Self::Xtensa(r) => r.supported_types(arch),
Self::Bpf(r) => r.supported_types(arch),
Self::Avr(r) => r.supported_types(arch),
Self::Msp430(r) => r.supported_types(arch),
Expand Down Expand Up @@ -638,6 +657,7 @@ impl InlineAsmRegClass {
}
InlineAsmArch::Bpf => Self::Bpf(BpfInlineAsmRegClass::parse(name)?),
InlineAsmArch::Avr => Self::Avr(AvrInlineAsmRegClass::parse(name)?),
InlineAsmArch::Xtensa => Self::Xtensa(XtensaInlineAsmRegClass::parse(name)?),
InlineAsmArch::Msp430 => Self::Msp430(Msp430InlineAsmRegClass::parse(name)?),
InlineAsmArch::M68k => Self::M68k(M68kInlineAsmRegClass::parse(name)?),
InlineAsmArch::CSKY => Self::CSKY(CSKYInlineAsmRegClass::parse(name)?),
Expand All @@ -660,6 +680,7 @@ impl InlineAsmRegClass {
Self::S390x(r) => r.valid_modifiers(arch),
Self::SpirV(r) => r.valid_modifiers(arch),
Self::Wasm(r) => r.valid_modifiers(arch),
Self::Xtensa(r) => r.valid_modifiers(arch),
Self::Bpf(r) => r.valid_modifiers(arch),
Self::Avr(r) => r.valid_modifiers(arch),
Self::Msp430(r) => r.valid_modifiers(arch),
Expand Down Expand Up @@ -704,6 +725,7 @@ impl fmt::Display for InlineAsmRegOrRegClass {
/// Set of types which can be used with a particular register class.
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum InlineAsmType {
I1,
I8,
I16,
I32,
Expand Down Expand Up @@ -731,6 +753,7 @@ impl InlineAsmType {

pub fn size(self) -> Size {
Size::from_bytes(match self {
Self::I1 => return Size::from_bits(1),
Self::I8 => 1,
Self::I16 => 2,
Self::I32 => 4,
Expand All @@ -756,6 +779,7 @@ impl InlineAsmType {
impl fmt::Display for InlineAsmType {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match *self {
Self::I1 => f.write_str("i1"),
Self::I8 => f.write_str("i8"),
Self::I16 => f.write_str("i16"),
Self::I32 => f.write_str("i32"),
Expand Down Expand Up @@ -853,6 +877,11 @@ pub fn allocatable_registers(
wasm::fill_reg_map(arch, reloc_model, target_features, target, &mut map);
map
}
InlineAsmArch::Xtensa => {
let mut map = xtensa::regclass_map();
xtensa::fill_reg_map(arch, reloc_model, target_features, target, &mut map);
map
}
InlineAsmArch::Bpf => {
let mut map = bpf::regclass_map();
bpf::fill_reg_map(arch, reloc_model, target_features, target, &mut map);
Expand Down
Loading

0 comments on commit 8c0f82e

Please sign in to comment.