Skip to content

Commit a9c8622

Browse files
committed
Feature gate fp, and other registers. Add Xtensa to asm! documentation.
1 parent 4e1bfd7 commit a9c8622

File tree

3 files changed

+68
-12
lines changed

3 files changed

+68
-12
lines changed

compiler/rustc_target/src/asm/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -593,6 +593,7 @@ impl fmt::Display for InlineAsmRegOrRegClass {
593593
/// Set of types which can be used with a particular register class.
594594
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
595595
pub enum InlineAsmType {
596+
I1,
596597
I8,
597598
I16,
598599
I32,
@@ -616,6 +617,7 @@ impl InlineAsmType {
616617

617618
pub fn size(self) -> Size {
618619
Size::from_bytes(match self {
620+
Self::I1 => return Size::from_bits(1),
619621
Self::I8 => 1,
620622
Self::I16 => 2,
621623
Self::I32 => 4,
@@ -637,6 +639,7 @@ impl InlineAsmType {
637639
impl fmt::Display for InlineAsmType {
638640
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
639641
match *self {
642+
Self::I1 => f.write_str("i1"),
640643
Self::I8 => f.write_str("i8"),
641644
Self::I16 => f.write_str("i16"),
642645
Self::I32 => f.write_str("i32"),

compiler/rustc_target/src/asm/xtensa.rs

Lines changed: 43 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,9 @@ impl XtensaInlineAsmRegClass {
3737
_arch: InlineAsmArch,
3838
) -> &'static [(InlineAsmType, Option<&'static str>)] {
3939
match self {
40-
Self::reg | Self::breg => types! { _: I8, I16, I32; },
41-
Self::freg => types! { "fp":F32; }, // TODO how does the dfpaccel feature interact F64 types? // _:F64;
40+
Self::reg => types! { _: I8, I16, I32; },
41+
Self::breg => types! { "bool": I1; },
42+
Self::freg => types! { "fp":F32; "dfpaccel":F64; },
4243
}
4344
}
4445
}
@@ -101,31 +102,57 @@ fn has_gpio_out(
101102
}
102103
}
103104

105+
fn frame_pointer_is_a7(
106+
_arch: InlineAsmArch,
107+
mut has_feature: impl FnMut(&str) -> bool,
108+
_target: &Target,
109+
) -> bool {
110+
has_feature("windowed")
111+
}
112+
113+
fn frame_pointer_a7(
114+
arch: InlineAsmArch,
115+
has_feature: impl FnMut(&str) -> bool,
116+
target: &Target,
117+
) -> Result<(), &'static str> {
118+
if frame_pointer_is_a7(arch, has_feature, target) {
119+
Err("the frame pointer (a7) cannot be used as an operand for inline asm")
120+
} else {
121+
Ok(())
122+
}
123+
}
104124

125+
fn frame_pointer_a15(
126+
arch: InlineAsmArch,
127+
has_feature: impl FnMut(&str) -> bool,
128+
target: &Target,
129+
) -> Result<(), &'static str> {
130+
if !frame_pointer_is_a7(arch, has_feature, target) {
131+
Err("the frame pointer (a15) cannot be used as an operand for inline asm")
132+
} else {
133+
Ok(())
134+
}
135+
}
105136

106137
def_regs! {
107138
Xtensa XtensaInlineAsmReg XtensaInlineAsmRegClass {
108-
a0: reg = ["a0"],
109-
sp: reg = ["sp", "a1"],
110139
a2: reg = ["a2"],
111140
a3: reg = ["a3"],
112141
a4: reg = ["a4"],
113142
a5: reg = ["a5"],
114143
a6: reg = ["a6"],
115-
a7: reg = ["a7"],
144+
a7: reg = ["a7"] % frame_pointer_a7,
116145
a8: reg = ["a8"],
117146
a9: reg = ["a9"],
118147
a10: reg = ["a10"],
119148
a11: reg = ["a11"],
120149
a12: reg = ["a12"],
121150
a13: reg = ["a13"],
122151
a14: reg = ["a14"],
123-
a15: reg = ["a15"],
124-
sar: reg = ["sar"], // TODO what feature enables this, if any?
125-
ddr: reg = ["ddr"], // TODO what feature enables this, if any?
126-
ps: reg = ["ps"], // TODO what feature enables this, if any?
127-
configid0: reg = ["configid0"], // TODO what feature enables this, if any?
128-
configid1: reg = ["configid1"], // TODO what feature enables this, if any?
152+
a15: reg = ["a15"] % frame_pointer_a15,
153+
sar: reg = ["sar"],
154+
configid0: reg = ["configid0"],
155+
configid1: reg = ["configid1"],
129156
lbeg: reg = ["lbeg"] % has_loop,
130157
lend: reg = ["lend"] % has_loop,
131158
lcount: reg = ["lcount"] % has_loop,
@@ -139,6 +166,7 @@ def_regs! {
139166
m3: reg = ["m3"] % has_mac16,
140167
windowbase: reg = ["windowbase"] % has_windowed,
141168
windowstart: reg = ["windowstart"] % has_windowed,
169+
ddr: reg = ["ddr"] % has_debug,
142170
ibreakenable: reg = ["ibreakenable"] % has_debug,
143171
ibreaka0: reg = ["ibreaka0"] % has_debug,
144172
ibreaka1: reg = ["ibreaka1"] % has_debug,
@@ -151,6 +179,7 @@ def_regs! {
151179
debugcause: reg = ["debugcause"] % has_debug,
152180
memctl: reg = ["memctl"] % has_memctl,
153181
atomctl: reg = ["atomctl"] % has_atomctl,
182+
ps: reg = ["ps"] % has_exception,
154183
epc1: reg = ["epc1"] % has_exception,
155184
epc2: reg = ["epc2"] % has_exception,
156185
epc3: reg = ["epc3"] % has_exception,
@@ -229,6 +258,9 @@ def_regs! {
229258
b13: breg = ["b13"] % has_bool,
230259
b14: breg = ["b14"] % has_bool,
231260
b15: breg = ["b15"] % has_bool,
261+
262+
#error = ["a0"] => "a0 is used internally by LLVM and cannot be used as an operand for inline asm",
263+
#error = ["sp", "a1"] => "sp is used internally by LLVM and cannot be used as an operand for inline asm",
232264
}
233265
}
234266

src/doc/unstable-book/src/library-features/asm.md

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ Inline assembly is currently supported on the following architectures:
3030
- Hexagon
3131
- MIPS32r2 and MIPS64r2
3232
- wasm32
33+
- Xtensa
3334
- BPF
3435

3536
## Basic usage
@@ -461,7 +462,7 @@ options := "options(" option *["," option] [","] ")"
461462
asm := "asm!(" format_string *("," format_string) *("," [ident "="] operand) ["," options] [","] ")"
462463
```
463464

464-
The macro will initially be supported only on ARM, AArch64, Hexagon, PowerPC, x86, x86-64 and RISC-V targets. Support for more targets may be added in the future. The compiler will emit an error if `asm!` is used on an unsupported target.
465+
The macro will initially be supported only on ARM, AArch64, Hexagon, PowerPC, Xtensa, x86, x86-64 and RISC-V targets. Support for more targets may be added in the future. The compiler will emit an error if `asm!` is used on an unsupported target.
465466

466467
[format-syntax]: https://doc.rust-lang.org/std/fmt/#syntax
467468

@@ -571,6 +572,9 @@ Here is the list of currently supported register classes:
571572
| PowerPC | `reg_nonzero` | | `r[1-31]` | `b` |
572573
| PowerPC | `freg` | `f[0-31]` | `f` |
573574
| wasm32 | `local` | None\* | `r` |
575+
| Xtensa | `reg` | `a[0-15]` | `r` |
576+
| Xtensa | `freg` | `f[0-15]` | `f` |
577+
| Xtensa | `breg` | `b[0-15]` | `b` |
574578
| BPF | `reg` | `r[0-10]` | `r` |
575579
| BPF | `wreg` | `w[0-10]` | `w` |
576580

@@ -620,6 +624,20 @@ Each register class has constraints on which value types they can be used with.
620624
| wasm32 | `local` | None | `i8` `i16` `i32` `i64` `f32` `f64` |
621625
| BPF | `reg` | None | `i8` `i16` `i32` `i64` |
622626
| BPF | `wreg` | `alu32` | `i8` `i16` `i32` |
627+
| Xtensa | `reg` | `a[0-15]`, `lbeg`, `lend`, `lcount` | `r` |
628+
| Xtensa | `reg` | `sar`, `br`, `litbase`, `scompare1` | `r` |
629+
| Xtensa | `reg` | `acclo`, `acchi`, `m0`, `m1`, `m2`, `m3` | `r` |
630+
| Xtensa | `reg` | `windowbase`, `windowstart`, `ibreakenable`, `memctl`, `atomctl`, `ddr` | `r` |
631+
| Xtensa | `reg` | `ibreaka0`, `ibreaka1`, `dbreaka0`, `dbreaka1`, `dbreakc0`, `dbreakc1`, `configid[0-1]` | `r` |
632+
| Xtensa | `reg` | `epc[1-7]`, `depc`, `eps[2-7]` | `r` |
633+
| Xtensa | `reg` | `excsave[1-7]`, `cpenable`, `interrupt`, `intclear`, `intenable` | `r` |
634+
| Xtensa | `reg` | `ps`, `vecbase`, `exccause`, `debugcause`, `ccount` | `r` |
635+
| Xtensa | `reg` | `prid`, `icount`, `icountlevel`, `excvaddr`, `ccompare[0-2]` | `r` |
636+
| Xtensa | `reg` | `excsave[1-7]`, `cpenable`, `interrupt`, `intclear`, `intenable` | `r` |
637+
| Xtensa | `reg` | `misc[0-3]`, `gpio_out`, `expstate`, `threadptr` | `r` |
638+
| Xtensa | `reg` | `fcr`, `fsr`, `f64r_lo`, `f64r_hi`, `f64s` | `r` |
639+
| Xtensa | `breg` | `b[0-15]` | `b` |
640+
| Xtensa | `freg` | `f[0-15]` | `f` |
623641

624642
> **Note**: For the purposes of the above table pointers, function pointers and `isize`/`usize` are treated as the equivalent integer type (`i16`/`i32`/`i64` depending on the target).
625643
@@ -760,6 +778,9 @@ The supported modifiers are a subset of LLVM's (and GCC's) [asm template argumen
760778
| PowerPC | `reg` | None | `0` | None |
761779
| PowerPC | `reg_nonzero` | None | `3` | `b` |
762780
| PowerPC | `freg` | None | `0` | None |
781+
| Xtensa | `reg` | None | `i8`, `i16`, `i32` |
782+
| Xtensa | `breg` | None | `i8`, `i16`, `i32` |
783+
| Xtensa | `freg` | None | `f32` |
763784

764785
> Notes:
765786
> - on ARM `e` / `f`: this prints the low or high doubleword register name of a NEON quad (128-bit) register.

0 commit comments

Comments
 (0)