-
Notifications
You must be signed in to change notification settings - Fork 12.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add asm!() support for hexagon #73214
Merged
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -374,7 +374,7 @@ options := "options(" option *["," option] [","] ")" | |
asm := "asm!(" format_string *("," [ident "="] operand) ["," options] [","] ")" | ||
``` | ||
|
||
The macro will initially be supported only on ARM, AArch64, 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. | ||
The macro will initially be supported only on ARM, AArch64, Hexagon, 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. | ||
|
||
[format-syntax]: https://doc.rust-lang.org/std/fmt/#syntax | ||
|
||
|
@@ -386,7 +386,7 @@ As with format strings, named arguments must appear after positional arguments. | |
|
||
The exact assembly code syntax is target-specific and opaque to the compiler except for the way operands are substituted into the template string to form the code passed to the assembler. | ||
|
||
The 4 targets specified in this RFC (x86, ARM, AArch64, RISC-V) all use the assembly code syntax of the GNU assembler (GAS). On x86, the `.intel_syntax noprefix` mode of GAS is used by default. On ARM, the `.syntax unified` mode is used. These targets impose an additional restriction on the assembly code: any assembler state (e.g. the current section which can be changed with `.section`) must be restored to its original value at the end of the asm string. Assembly code that does not conform to the GAS syntax will result in assembler-specific behavior. | ||
The 5 targets specified in this RFC (x86, ARM, AArch64, RISC-V, Hexagon) all use the assembly code syntax of the GNU assembler (GAS). On x86, the `.intel_syntax noprefix` mode of GAS is used by default. On ARM, the `.syntax unified` mode is used. These targets impose an additional restriction on the assembly code: any assembler state (e.g. the current section which can be changed with `.section`) must be restored to its original value at the end of the asm string. Assembly code that does not conform to the GAS syntax will result in assembler-specific behavior. | ||
|
||
[rfc-2795]: https://github.com/rust-lang/rfcs/pull/2795 | ||
|
||
|
@@ -473,6 +473,7 @@ Here is the list of currently supported register classes: | |
| NVPTX | `reg64` | None\* | `l` | | ||
| RISC-V | `reg` | `x1`, `x[5-7]`, `x[9-15]`, `x[16-31]` (non-RV32E) | `r` | | ||
| RISC-V | `freg` | `f[0-31]` | `f` | | ||
| Hexagon | `reg` | `r[0-28]` | `r` | | ||
|
||
> **Note**: On x86 we treat `reg_byte` differently from `reg` because the compiler can allocate `al` and `ah` separately whereas `reg` reserves the whole register. | ||
> | ||
|
@@ -507,6 +508,7 @@ Each register class has constraints on which value types they can be used with. | |
| RISC-V64 | `reg` | None | `i8`, `i16`, `i32`, `f32`, `i64`, `f64` | | ||
| RISC-V | `freg` | `f` | `f32` | | ||
| RISC-V | `freg` | `d` | `f64` | | ||
| Hexagon | `reg` | None | `i8`, `i16`, `i32`, `f32` | | ||
|
||
> **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). | ||
|
||
|
@@ -563,13 +565,16 @@ Some registers have multiple names. These are all treated by the compiler as ide | |
| RISC-V | `f[10-17]` | `fa[0-7]` | | ||
| RISC-V | `f[18-27]` | `fs[2-11]` | | ||
| RISC-V | `f[28-31]` | `ft[8-11]` | | ||
| Hexagon | `r29` | `sp` | | ||
| Hexagon | `r30` | `fr` | | ||
| Hexagon | `r31` | `lr` | | ||
|
||
Some registers cannot be used for input or output operands: | ||
|
||
| Architecture | Unsupported register | Reason | | ||
| ------------ | -------------------- | ------ | | ||
| All | `sp` | The stack pointer must be restored to its original value at the end of an asm code block. | | ||
| All | `bp` (x86), `r11` (ARM), `x29` (AArch64), `x8` (RISC-V) | The frame pointer cannot be used as an input or output. | | ||
| All | `bp` (x86), `r11` (ARM), `x29` (AArch64), `x8` (RISC-V), `fr` (Hexagon) | The frame pointer cannot be used as an input or output. | | ||
| x86 | `k0` | This is a constant zero register which can't be modified. | | ||
| x86 | `ip` | This is the program counter, not a real register. | | ||
| x86 | `mm[0-7]` | MMX registers are not currently supported (but may be in the future). | | ||
|
@@ -578,6 +583,7 @@ Some registers cannot be used for input or output operands: | |
| ARM | `pc` | This is the program counter, not a real register. | | ||
| RISC-V | `x0` | This is a constant zero register which can't be modified. | | ||
| RISC-V | `gp`, `tp` | These registers are reserved and cannot be used as inputs or outputs. | | ||
| Hexagon | `lr` | This is the link register which cannot be used as an input or output. | | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add |
||
|
||
## Template modifiers | ||
|
||
|
@@ -623,6 +629,7 @@ The supported modifiers are a subset of LLVM's (and GCC's) [asm template argumen | |
| NVPTX | `reg64` | None | `rd0` | None | | ||
| RISC-V | `reg` | None | `x1` | None | | ||
| RISC-V | `freg` | None | `f0` | None | | ||
| Hexagon | `reg` | None | `r0` | None | | ||
|
||
> Notes: | ||
> - on ARM `e` / `f`: this prints the low or high doubleword register name of a NEON quad (128-bit) register. | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
use super::{InlineAsmArch, InlineAsmType}; | ||
use rustc_macros::HashStable_Generic; | ||
use std::fmt; | ||
|
||
def_reg_class! { | ||
Hexagon HexagonInlineAsmRegClass { | ||
reg, | ||
androm3da marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
} | ||
|
||
impl HexagonInlineAsmRegClass { | ||
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::reg => types! { _: I8, I16, I32, F32; }, | ||
} | ||
} | ||
} | ||
|
||
def_regs! { | ||
Hexagon HexagonInlineAsmReg HexagonInlineAsmRegClass { | ||
r0: reg = ["r0"], | ||
r1: reg = ["r1"], | ||
r2: reg = ["r2"], | ||
r3: reg = ["r3"], | ||
r4: reg = ["r4"], | ||
r5: reg = ["r5"], | ||
r6: reg = ["r6"], | ||
r7: reg = ["r7"], | ||
r8: reg = ["r8"], | ||
r9: reg = ["r9"], | ||
r10: reg = ["r10"], | ||
r11: reg = ["r11"], | ||
r12: reg = ["r12"], | ||
r13: reg = ["r13"], | ||
r14: reg = ["r14"], | ||
r15: reg = ["r15"], | ||
r16: reg = ["r16"], | ||
r17: reg = ["r17"], | ||
r18: reg = ["r18"], | ||
r19: reg = ["r19"], | ||
r20: reg = ["r20"], | ||
r21: reg = ["r21"], | ||
r22: reg = ["r22"], | ||
r23: reg = ["r23"], | ||
r24: reg = ["r24"], | ||
r25: reg = ["r25"], | ||
r26: reg = ["r26"], | ||
r27: reg = ["r27"], | ||
r28: reg = ["r28"], | ||
#error = ["r29", "sp"] => | ||
"the stack pointer cannot be used as an operand for inline asm", | ||
#error = ["r30", "fr"] => | ||
"the frame register cannot be used as an operand for inline asm", | ||
#error = ["r31", "lr"] => | ||
"the link register cannot be used as an operand for inline asm", | ||
} | ||
} | ||
|
||
impl HexagonInlineAsmReg { | ||
pub fn emit( | ||
self, | ||
out: &mut dyn fmt::Write, | ||
_arch: InlineAsmArch, | ||
_modifier: Option<char>, | ||
) -> fmt::Result { | ||
out.write_str(self.name()) | ||
} | ||
|
||
pub fn overlapping_regs(self, mut _cb: impl FnMut(HexagonInlineAsmReg)) {} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All registers can be used as inputs on Hexagon, that is the architecture doesn't not differentiate between
r0
andr29
orr30
, except for a small set of instructions which require fewer bits to encode registers. As a matter of fact, most loads/stores to stack are done viar29
orr30
(i.e.sp
orfp
), and a return from a function that does not allocate stack space is done viajumpr r31
.All of these registers can also be modified, but that's typically a bad idea.