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 <[email protected]>
  • Loading branch information
MabezDev and taiki-e committed Feb 18, 2025
1 parent db286d5 commit 8d1c312
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 @@ -279,6 +279,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 @@ -682,6 +683,9 @@ fn reg_to_llvm(reg: InlineAsmRegOrRegClass, layout: Option<&TyAndLayout<'_>>) ->
| X86InlineAsmRegClass::kreg0
| X86InlineAsmRegClass::tmm_reg,
) => unreachable!("clobber-only"),
Xtensa(XtensaInlineAsmRegClass::freg) => "f",
Xtensa(XtensaInlineAsmRegClass::reg) => "r",
Xtensa(XtensaInlineAsmRegClass::breg) => "b",
Wasm(WasmInlineAsmRegClass::local) => "r",
Bpf(BpfInlineAsmRegClass::reg) => "r",
Bpf(BpfInlineAsmRegClass::wreg) => "w",
Expand Down Expand Up @@ -781,6 +785,7 @@ fn modifier_to_llvm(
| X86InlineAsmRegClass::kreg0
| X86InlineAsmRegClass::tmm_reg,
) => unreachable!("clobber-only"),
Xtensa(_) => None,
Wasm(WasmInlineAsmRegClass::local) => None,
Bpf(_) => None,
Avr(AvrInlineAsmRegClass::reg_pair)
Expand Down Expand Up @@ -850,6 +855,9 @@ fn dummy_output_type<'ll>(cx: &CodegenCx<'ll, '_>, reg: InlineAsmRegClass) -> &'
| X86InlineAsmRegClass::kreg0
| X86InlineAsmRegClass::tmm_reg,
) => unreachable!("clobber-only"),
Xtensa(XtensaInlineAsmRegClass::reg) => cx.type_i32(),
Xtensa(XtensaInlineAsmRegClass::freg) => cx.type_f32(),
Xtensa(XtensaInlineAsmRegClass::breg) => cx.type_i1(),
Wasm(WasmInlineAsmRegClass::local) => cx.type_i32(),
Bpf(BpfInlineAsmRegClass::reg) => cx.type_i64(),
Bpf(BpfInlineAsmRegClass::wreg) => cx.type_i32(),
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 @@ -490,6 +490,7 @@ symbols! {
async_iterator,
async_iterator_poll_next,
async_trait_bounds,
atomctl,
atomic,
atomic_mod,
atomics,
Expand Down Expand Up @@ -535,6 +536,7 @@ symbols! {
braced_empty_structs,
branch,
breakpoint,
breg,
bridge,
bswap,
btreemap_contains_key,
Expand Down Expand Up @@ -678,6 +680,7 @@ symbols! {
constant,
constructor,
convert_identity,
coprocessor,
copy,
copy_closures,
copy_nonoverlapping,
Expand Down Expand Up @@ -771,6 +774,7 @@ symbols! {
derive_smart_pointer,
destruct,
destructuring_assignment,
dfpaccel,
diagnostic,
diagnostic_namespace,
direct,
Expand Down Expand Up @@ -836,6 +840,7 @@ symbols! {
ermsb_target_feature,
exact_div,
except,
exception,
exchange_malloc,
exclusive_range_pattern,
exhaustive_integer_patterns,
Expand All @@ -859,6 +864,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 @@ -971,6 +977,7 @@ symbols! {
format_macro,
format_placeholder,
format_unsafe_arg,
fp,
freeze,
freeze_impls,
freg,
Expand Down Expand Up @@ -1035,6 +1042,7 @@ symbols! {
hashset_iter_ty,
hexagon_target_feature,
hidden,
highpriinterrupts,
hint,
homogeneous_aggregate,
host,
Expand Down Expand Up @@ -1116,6 +1124,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 @@ -1208,6 +1218,7 @@ symbols! {
loop_break_value,
lt,
m68k_target_feature,
mac16,
macro_at_most_once_rep,
macro_attributes_in_derive_output,
macro_escape,
Expand Down Expand Up @@ -1251,6 +1262,7 @@ symbols! {
mem_variant_count,
mem_zeroed,
member_constraints,
memctl,
memory,
memtag,
message,
Expand Down Expand Up @@ -1306,6 +1318,8 @@ symbols! {
mir_unwind_unreachable,
mir_variant,
miri,
misc,
miscsr,
mmx_reg,
modifiers,
module,
Expand Down Expand Up @@ -1535,6 +1549,8 @@ symbols! {
prelude_import,
preserves_flags,
prfchw_target_feature,
prid,
primitive,
print_macro,
println_macro,
proc_dash_macro: "proc-macro",
Expand Down Expand Up @@ -1793,8 +1809,10 @@ symbols! {
rustdoc_missing_doc_code_examples,
rustfmt,
rvalue_static_promotion,
rvector,
rwpi,
s,
s32c1i,
s390x_target_feature,
safety,
sanitize,
Expand Down Expand Up @@ -2008,10 +2026,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 @@ -2205,6 +2225,8 @@ symbols! {
wasm_import_module,
wasm_target_feature,
while_let,
width,
windowed,
windows,
windows_subsystem,
with_negative_coherence,
Expand All @@ -2226,8 +2248,10 @@ symbols! {
x87_reg,
x87_target_feature,
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 @@ -195,6 +195,7 @@ mod sparc;
mod spirv;
mod wasm;
mod x86;
mod xtensa;

pub use aarch64::{AArch64InlineAsmReg, AArch64InlineAsmRegClass};
pub use arm::{ArmInlineAsmReg, ArmInlineAsmRegClass};
Expand All @@ -213,6 +214,7 @@ pub use s390x::{S390xInlineAsmReg, S390xInlineAsmRegClass};
pub use sparc::{SparcInlineAsmReg, SparcInlineAsmRegClass};
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 @@ -237,6 +239,7 @@ pub enum InlineAsmArch {
SpirV,
Wasm32,
Wasm64,
Xtensa,
Bpf,
Avr,
Msp430,
Expand Down Expand Up @@ -269,6 +272,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 @@ -295,6 +299,7 @@ pub enum InlineAsmReg {
Sparc(SparcInlineAsmReg),
SpirV(SpirVInlineAsmReg),
Wasm(WasmInlineAsmReg),
Xtensa(XtensaInlineAsmReg),
Bpf(BpfInlineAsmReg),
Avr(AvrInlineAsmReg),
Msp430(Msp430InlineAsmReg),
Expand All @@ -317,6 +322,7 @@ impl InlineAsmReg {
Self::Mips(r) => r.name(),
Self::S390x(r) => r.name(),
Self::Sparc(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 @@ -338,6 +344,7 @@ impl InlineAsmReg {
Self::Mips(r) => InlineAsmRegClass::Mips(r.reg_class()),
Self::S390x(r) => InlineAsmRegClass::S390x(r.reg_class()),
Self::Sparc(r) => InlineAsmRegClass::Sparc(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 @@ -369,6 +376,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::Sparc | InlineAsmArch::Sparc64 => {
Self::Sparc(SparcInlineAsmReg::parse(name)?)
Expand Down Expand Up @@ -408,6 +418,7 @@ impl InlineAsmReg {
Self::Sparc(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 @@ -434,6 +445,7 @@ impl InlineAsmReg {
Self::Mips(r) => r.emit(out, arch, modifier),
Self::S390x(r) => r.emit(out, arch, modifier),
Self::Sparc(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 @@ -455,6 +467,7 @@ impl InlineAsmReg {
Self::Mips(_) => cb(self),
Self::S390x(r) => r.overlapping_regs(|r| cb(Self::S390x(r))),
Self::Sparc(_) => 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 @@ -481,6 +494,7 @@ pub enum InlineAsmRegClass {
Sparc(SparcInlineAsmRegClass),
SpirV(SpirVInlineAsmRegClass),
Wasm(WasmInlineAsmRegClass),
Xtensa(XtensaInlineAsmRegClass),
Bpf(BpfInlineAsmRegClass),
Avr(AvrInlineAsmRegClass),
Msp430(Msp430InlineAsmRegClass),
Expand All @@ -506,6 +520,7 @@ impl InlineAsmRegClass {
Self::Sparc(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 Down Expand Up @@ -533,6 +548,7 @@ impl InlineAsmRegClass {
Self::Sparc(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::Sparc),
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 @@ -563,6 +579,7 @@ impl InlineAsmRegClass {
Self::Sparc(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 @@ -593,6 +610,7 @@ impl InlineAsmRegClass {
Self::Sparc(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 @@ -626,6 +644,7 @@ impl InlineAsmRegClass {
Self::Sparc(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 @@ -666,6 +685,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 @@ -689,6 +709,7 @@ impl InlineAsmRegClass {
Self::Sparc(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 @@ -736,6 +757,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 @@ -763,6 +785,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 @@ -788,6 +811,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 @@ -890,6 +914,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 8d1c312

Please sign in to comment.