Skip to content

Commit 93ee290

Browse files
committed
asm! support the the Xtensa architecture
1 parent 8fc1989 commit 93ee290

File tree

7 files changed

+514
-1
lines changed

7 files changed

+514
-1
lines changed

compiler/rustc_codegen_llvm/src/asm.rs

+8
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,7 @@ impl AsmBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> {
288288
InlineAsmArch::Mips | InlineAsmArch::Mips64 => {}
289289
InlineAsmArch::SpirV => {}
290290
InlineAsmArch::Wasm32 => {}
291+
InlineAsmArch::Xtensa => {}
291292
InlineAsmArch::Bpf => {}
292293
}
293294
}
@@ -594,6 +595,9 @@ fn reg_to_llvm(reg: InlineAsmRegOrRegClass, layout: Option<&TyAndLayout<'tcx>>)
594595
InlineAsmRegClass::X86(X86InlineAsmRegClass::zmm_reg) => "v",
595596
InlineAsmRegClass::X86(X86InlineAsmRegClass::kreg) => "^Yk",
596597
InlineAsmRegClass::Wasm(WasmInlineAsmRegClass::local) => "r",
598+
InlineAsmRegClass::Xtensa(XtensaInlineAsmRegClass::reg) => "r",
599+
InlineAsmRegClass::Xtensa(XtensaInlineAsmRegClass::freg) => "f",
600+
InlineAsmRegClass::Xtensa(XtensaInlineAsmRegClass::breg) => "b",
597601
InlineAsmRegClass::Bpf(BpfInlineAsmRegClass::reg) => "r",
598602
InlineAsmRegClass::Bpf(BpfInlineAsmRegClass::wreg) => "w",
599603
InlineAsmRegClass::SpirV(SpirVInlineAsmRegClass::reg) => {
@@ -637,6 +641,7 @@ fn modifier_to_llvm(
637641
InlineAsmRegClass::Mips(_) => None,
638642
InlineAsmRegClass::Nvptx(_) => None,
639643
InlineAsmRegClass::PowerPC(_) => None,
644+
InlineAsmRegClass::Xtensa(_) => None,
640645
InlineAsmRegClass::RiscV(RiscVInlineAsmRegClass::reg)
641646
| InlineAsmRegClass::RiscV(RiscVInlineAsmRegClass::freg) => None,
642647
InlineAsmRegClass::X86(X86InlineAsmRegClass::reg)
@@ -712,6 +717,9 @@ fn dummy_output_type(cx: &CodegenCx<'ll, 'tcx>, reg: InlineAsmRegClass) -> &'ll
712717
| InlineAsmRegClass::X86(X86InlineAsmRegClass::zmm_reg) => cx.type_f32(),
713718
InlineAsmRegClass::X86(X86InlineAsmRegClass::kreg) => cx.type_i16(),
714719
InlineAsmRegClass::Wasm(WasmInlineAsmRegClass::local) => cx.type_i32(),
720+
InlineAsmRegClass::Xtensa(XtensaInlineAsmRegClass::reg) => cx.type_i32(),
721+
InlineAsmRegClass::Xtensa(XtensaInlineAsmRegClass::freg) => cx.type_f32(),
722+
InlineAsmRegClass::Xtensa(XtensaInlineAsmRegClass::breg) => cx.type_i1(),
715723
InlineAsmRegClass::Bpf(BpfInlineAsmRegClass::reg) => cx.type_i64(),
716724
InlineAsmRegClass::Bpf(BpfInlineAsmRegClass::wreg) => cx.type_i32(),
717725
InlineAsmRegClass::SpirV(SpirVInlineAsmRegClass::reg) => {

compiler/rustc_codegen_ssa/src/target_features.rs

+30
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,34 @@ const WASM_ALLOWED_FEATURES: &[(&str, Option<Symbol>)] = &[
210210
("nontrapping-fptoint", Some(sym::wasm_target_feature)),
211211
];
212212

213+
const XTENSA_ALLOWED_FEATURES: &[(&str, Option<Symbol>)] = &[
214+
("fp", Some(sym::xtensa_target_feature)),
215+
("windowed", Some(sym::xtensa_target_feature)),
216+
("bool", Some(sym::xtensa_target_feature)),
217+
("loop", Some(sym::xtensa_target_feature)),
218+
("sext", Some(sym::xtensa_target_feature)),
219+
("nsa", Some(sym::xtensa_target_feature)),
220+
("mul32", Some(sym::xtensa_target_feature)),
221+
("mul32high", Some(sym::xtensa_target_feature)),
222+
("div32", Some(sym::xtensa_target_feature)),
223+
("mac16", Some(sym::xtensa_target_feature)),
224+
("dfpaccel", Some(sym::xtensa_target_feature)),
225+
("s32c1i", Some(sym::xtensa_target_feature)),
226+
("threadptr", Some(sym::xtensa_target_feature)),
227+
("extendedl32r", Some(sym::xtensa_target_feature)),
228+
("atomctl", Some(sym::xtensa_target_feature)),
229+
("memctl", Some(sym::xtensa_target_feature)),
230+
("debug", Some(sym::xtensa_target_feature)),
231+
("exception", Some(sym::xtensa_target_feature)),
232+
("coprocessor", Some(sym::xtensa_target_feature)),
233+
("interrupt", Some(sym::xtensa_target_feature)),
234+
("rvector", Some(sym::xtensa_target_feature)),
235+
("timerint", Some(sym::xtensa_target_feature)),
236+
("prid", Some(sym::xtensa_target_feature)),
237+
("regprotect", Some(sym::xtensa_target_feature)),
238+
("miscsr", Some(sym::xtensa_target_feature)),
239+
];
240+
213241
const BPF_ALLOWED_FEATURES: &[(&str, Option<Symbol>)] = &[("alu32", Some(sym::bpf_target_feature))];
214242

215243
/// When rustdoc is running, provide a list of all known features so that all their respective
@@ -226,6 +254,7 @@ pub fn all_known_features() -> impl Iterator<Item = (&'static str, Option<Symbol
226254
.chain(MIPS_ALLOWED_FEATURES.iter())
227255
.chain(RISCV_ALLOWED_FEATURES.iter())
228256
.chain(WASM_ALLOWED_FEATURES.iter())
257+
.chain(XTENSA_ALLOWED_FEATURES.iter())
229258
.chain(BPF_ALLOWED_FEATURES.iter())
230259
.cloned()
231260
}
@@ -240,6 +269,7 @@ pub fn supported_target_features(sess: &Session) -> &'static [(&'static str, Opt
240269
"powerpc" | "powerpc64" => POWERPC_ALLOWED_FEATURES,
241270
"riscv32" | "riscv64" => RISCV_ALLOWED_FEATURES,
242271
"wasm32" | "wasm64" => WASM_ALLOWED_FEATURES,
272+
"xtensa" => XTENSA_ALLOWED_FEATURES,
243273
"bpf" => BPF_ALLOWED_FEATURES,
244274
_ => &[],
245275
}

compiler/rustc_span/src/symbol.rs

+2
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,7 @@ symbols! {
332332
braced_empty_structs,
333333
branch,
334334
breakpoint,
335+
breg,
335336
bridge,
336337
bswap,
337338
c_str,
@@ -1336,6 +1337,7 @@ symbols! {
13361337
wreg,
13371338
write_bytes,
13381339
xmm_reg,
1340+
xtensa_target_feature,
13391341
ymm_reg,
13401342
zmm_reg,
13411343
}

compiler/rustc_target/src/asm/mod.rs

+28
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,7 @@ mod riscv;
157157
mod spirv;
158158
mod wasm;
159159
mod x86;
160+
mod xtensa;
160161

161162
pub use aarch64::{AArch64InlineAsmReg, AArch64InlineAsmRegClass};
162163
pub use arm::{ArmInlineAsmReg, ArmInlineAsmRegClass};
@@ -168,6 +169,7 @@ pub use powerpc::{PowerPCInlineAsmReg, PowerPCInlineAsmRegClass};
168169
pub use riscv::{RiscVInlineAsmReg, RiscVInlineAsmRegClass};
169170
pub use spirv::{SpirVInlineAsmReg, SpirVInlineAsmRegClass};
170171
pub use wasm::{WasmInlineAsmReg, WasmInlineAsmRegClass};
172+
pub use xtensa::{XtensaInlineAsmReg, XtensaInlineAsmRegClass};
171173
pub use x86::{X86InlineAsmReg, X86InlineAsmRegClass};
172174

173175
#[derive(Copy, Clone, Encodable, Decodable, Debug, Eq, PartialEq, Hash)]
@@ -186,6 +188,7 @@ pub enum InlineAsmArch {
186188
PowerPC64,
187189
SpirV,
188190
Wasm32,
191+
Xtensa,
189192
Bpf,
190193
}
191194

@@ -208,6 +211,7 @@ impl FromStr for InlineAsmArch {
208211
"mips64" => Ok(Self::Mips64),
209212
"spirv" => Ok(Self::SpirV),
210213
"wasm32" => Ok(Self::Wasm32),
214+
"xtensa" => Ok(Self::Xtensa),
211215
"bpf" => Ok(Self::Bpf),
212216
_ => Err(()),
213217
}
@@ -237,6 +241,7 @@ pub enum InlineAsmReg {
237241
Mips(MipsInlineAsmReg),
238242
SpirV(SpirVInlineAsmReg),
239243
Wasm(WasmInlineAsmReg),
244+
Xtensa(XtensaInlineAsmReg),
240245
Bpf(BpfInlineAsmReg),
241246
// Placeholder for invalid register constraints for the current target
242247
Err,
@@ -252,6 +257,7 @@ impl InlineAsmReg {
252257
Self::PowerPC(r) => r.name(),
253258
Self::Hexagon(r) => r.name(),
254259
Self::Mips(r) => r.name(),
260+
Self::Xtensa(r) => r.name(),
255261
Self::Bpf(r) => r.name(),
256262
Self::Err => "<reg>",
257263
}
@@ -266,6 +272,7 @@ impl InlineAsmReg {
266272
Self::PowerPC(r) => InlineAsmRegClass::PowerPC(r.reg_class()),
267273
Self::Hexagon(r) => InlineAsmRegClass::Hexagon(r.reg_class()),
268274
Self::Mips(r) => InlineAsmRegClass::Mips(r.reg_class()),
275+
Self::Xtensa(r) => InlineAsmRegClass::Xtensa(r.reg_class()),
269276
Self::Bpf(r) => InlineAsmRegClass::Bpf(r.reg_class()),
270277
Self::Err => InlineAsmRegClass::Err,
271278
}
@@ -311,6 +318,9 @@ impl InlineAsmReg {
311318
InlineAsmArch::Wasm32 => {
312319
Self::Wasm(WasmInlineAsmReg::parse(arch, has_feature, target, &name)?)
313320
}
321+
InlineAsmArch::Xtensa => {
322+
Self::Xtensa(XtensaInlineAsmReg::parse(arch, has_feature, target, &name)?)
323+
}
314324
InlineAsmArch::Bpf => {
315325
Self::Bpf(BpfInlineAsmReg::parse(arch, has_feature, target, &name)?)
316326
}
@@ -333,6 +343,7 @@ impl InlineAsmReg {
333343
Self::PowerPC(r) => r.emit(out, arch, modifier),
334344
Self::Hexagon(r) => r.emit(out, arch, modifier),
335345
Self::Mips(r) => r.emit(out, arch, modifier),
346+
Self::Xtensa(r) => r.emit(out, arch, modifier),
336347
Self::Bpf(r) => r.emit(out, arch, modifier),
337348
Self::Err => unreachable!("Use of InlineAsmReg::Err"),
338349
}
@@ -347,6 +358,7 @@ impl InlineAsmReg {
347358
Self::PowerPC(_) => cb(self),
348359
Self::Hexagon(r) => r.overlapping_regs(|r| cb(Self::Hexagon(r))),
349360
Self::Mips(_) => cb(self),
361+
Self::Xtensa(_) => cb(self),
350362
Self::Bpf(r) => r.overlapping_regs(|r| cb(Self::Bpf(r))),
351363
Self::Err => unreachable!("Use of InlineAsmReg::Err"),
352364
}
@@ -376,6 +388,7 @@ pub enum InlineAsmRegClass {
376388
Mips(MipsInlineAsmRegClass),
377389
SpirV(SpirVInlineAsmRegClass),
378390
Wasm(WasmInlineAsmRegClass),
391+
Xtensa(XtensaInlineAsmRegClass),
379392
Bpf(BpfInlineAsmRegClass),
380393
// Placeholder for invalid register constraints for the current target
381394
Err,
@@ -394,6 +407,7 @@ impl InlineAsmRegClass {
394407
Self::Mips(r) => r.name(),
395408
Self::SpirV(r) => r.name(),
396409
Self::Wasm(r) => r.name(),
410+
Self::Xtensa(r) => r.name(),
397411
Self::Bpf(r) => r.name(),
398412
Self::Err => rustc_span::symbol::sym::reg,
399413
}
@@ -414,6 +428,7 @@ impl InlineAsmRegClass {
414428
Self::Mips(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::Mips),
415429
Self::SpirV(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::SpirV),
416430
Self::Wasm(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::Wasm),
431+
Self::Xtensa(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::Xtensa),
417432
Self::Bpf(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::Bpf),
418433
Self::Err => unreachable!("Use of InlineAsmRegClass::Err"),
419434
}
@@ -441,6 +456,7 @@ impl InlineAsmRegClass {
441456
Self::Mips(r) => r.suggest_modifier(arch, ty),
442457
Self::SpirV(r) => r.suggest_modifier(arch, ty),
443458
Self::Wasm(r) => r.suggest_modifier(arch, ty),
459+
Self::Xtensa(r) => r.suggest_modifier(arch, ty),
444460
Self::Bpf(r) => r.suggest_modifier(arch, ty),
445461
Self::Err => unreachable!("Use of InlineAsmRegClass::Err"),
446462
}
@@ -464,6 +480,7 @@ impl InlineAsmRegClass {
464480
Self::Mips(r) => r.default_modifier(arch),
465481
Self::SpirV(r) => r.default_modifier(arch),
466482
Self::Wasm(r) => r.default_modifier(arch),
483+
Self::Xtensa(r) => r.default_modifier(arch),
467484
Self::Bpf(r) => r.default_modifier(arch),
468485
Self::Err => unreachable!("Use of InlineAsmRegClass::Err"),
469486
}
@@ -486,6 +503,7 @@ impl InlineAsmRegClass {
486503
Self::Mips(r) => r.supported_types(arch),
487504
Self::SpirV(r) => r.supported_types(arch),
488505
Self::Wasm(r) => r.supported_types(arch),
506+
Self::Xtensa(r) => r.supported_types(arch),
489507
Self::Bpf(r) => r.supported_types(arch),
490508
Self::Err => unreachable!("Use of InlineAsmRegClass::Err"),
491509
}
@@ -511,6 +529,7 @@ impl InlineAsmRegClass {
511529
}
512530
InlineAsmArch::SpirV => Self::SpirV(SpirVInlineAsmRegClass::parse(arch, name)?),
513531
InlineAsmArch::Wasm32 => Self::Wasm(WasmInlineAsmRegClass::parse(arch, name)?),
532+
InlineAsmArch::Xtensa => Self::Xtensa(XtensaInlineAsmRegClass::parse(arch, name)?),
514533
InlineAsmArch::Bpf => Self::Bpf(BpfInlineAsmRegClass::parse(arch, name)?),
515534
})
516535
}
@@ -529,6 +548,7 @@ impl InlineAsmRegClass {
529548
Self::Mips(r) => r.valid_modifiers(arch),
530549
Self::SpirV(r) => r.valid_modifiers(arch),
531550
Self::Wasm(r) => r.valid_modifiers(arch),
551+
Self::Xtensa(r) => r.valid_modifiers(arch),
532552
Self::Bpf(r) => r.valid_modifiers(arch),
533553
Self::Err => unreachable!("Use of InlineAsmRegClass::Err"),
534554
}
@@ -573,6 +593,7 @@ impl fmt::Display for InlineAsmRegOrRegClass {
573593
/// Set of types which can be used with a particular register class.
574594
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
575595
pub enum InlineAsmType {
596+
I1,
576597
I8,
577598
I16,
578599
I32,
@@ -596,6 +617,7 @@ impl InlineAsmType {
596617

597618
pub fn size(self) -> Size {
598619
Size::from_bytes(match self {
620+
Self::I1 => return Size::from_bits(1),
599621
Self::I8 => 1,
600622
Self::I16 => 2,
601623
Self::I32 => 4,
@@ -617,6 +639,7 @@ impl InlineAsmType {
617639
impl fmt::Display for InlineAsmType {
618640
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
619641
match *self {
642+
Self::I1 => f.write_str("i1"),
620643
Self::I8 => f.write_str("i8"),
621644
Self::I16 => f.write_str("i16"),
622645
Self::I32 => f.write_str("i32"),
@@ -699,6 +722,11 @@ pub fn allocatable_registers(
699722
wasm::fill_reg_map(arch, has_feature, target, &mut map);
700723
map
701724
}
725+
InlineAsmArch::Xtensa => {
726+
let mut map = xtensa::regclass_map();
727+
xtensa::fill_reg_map(arch, has_feature, target, &mut map);
728+
map
729+
}
702730
InlineAsmArch::Bpf => {
703731
let mut map = bpf::regclass_map();
704732
bpf::fill_reg_map(arch, has_feature, target, &mut map);

0 commit comments

Comments
 (0)