@@ -54,111 +54,26 @@ string parsing. The remaining options are mostly passed through to LLVM with lit
5454
5555## AST
5656
57- ` InlineAsm ` is represented as an expression in the AST:
58-
59- ``` rust
60- pub struct InlineAsm {
61- pub template : Vec <InlineAsmTemplatePiece >,
62- pub template_strs : Box <[(Symbol , Option <Symbol >, Span )]>,
63- pub operands : Vec <(InlineAsmOperand , Span )>,
64- pub clobber_abi : Option <(Symbol , Span )>,
65- pub options : InlineAsmOptions ,
66- pub line_spans : Vec <Span >,
67- }
68-
69- pub enum InlineAsmRegOrRegClass {
70- Reg (Symbol ),
71- RegClass (Symbol ),
72- }
73-
74- pub enum InlineAsmOperand {
75- In {
76- reg : InlineAsmRegOrRegClass ,
77- expr : P <Expr >,
78- },
79- Out {
80- reg : InlineAsmRegOrRegClass ,
81- late : bool ,
82- expr : Option <P <Expr >>,
83- },
84- InOut {
85- reg : InlineAsmRegOrRegClass ,
86- late : bool ,
87- expr : P <Expr >,
88- },
89- SplitInOut {
90- reg : InlineAsmRegOrRegClass ,
91- late : bool ,
92- in_expr : P <Expr >,
93- out_expr : Option <P <Expr >>,
94- },
95- Const {
96- anon_const : AnonConst ,
97- },
98- Sym {
99- expr : P <Expr >,
100- },
101- }
102- ```
57+ ` InlineAsm ` is represented as an expression in the AST with the [ ` ast::InlineAsm ` type] [ inline_asm_ast ] .
10358
10459The ` asm! ` macro is implemented in ` rustc_builtin_macros ` and outputs an ` InlineAsm ` AST node. The
10560template string is parsed using ` fmt_macros ` , positional and named operands are resolved to
10661explicit operand indices. Since target information is not available to macro invocations,
10762validation of the registers and register classes is deferred to AST lowering.
10863
64+ [ inline_asm_ast ] : https://doc.rust-lang.org/nightly/nightly-rustc/rustc_ast/ast/struct.InlineAsm.html
65+
10966## HIR
11067
111- ` InlineAsm ` is represented as an expression in the HIR:
112-
113- ``` rust
114- pub struct InlineAsm <'hir > {
115- pub template : & 'hir [InlineAsmTemplatePiece ],
116- pub template_strs : & 'hir [(Symbol , Option <Symbol >, Span )],
117- pub operands : & 'hir [(InlineAsmOperand <'hir >, Span )],
118- pub options : InlineAsmOptions ,
119- pub line_spans : & 'hir [Span ],
120- }
121-
122- pub enum InlineAsmRegOrRegClass {
123- Reg (InlineAsmReg ),
124- RegClass (InlineAsmRegClass ),
125- }
126-
127- pub enum InlineAsmOperand <'hir > {
128- In {
129- reg : InlineAsmRegOrRegClass ,
130- expr : Expr <'hir >,
131- },
132- Out {
133- reg : InlineAsmRegOrRegClass ,
134- late : bool ,
135- expr : Option <Expr <'hir >>,
136- },
137- InOut {
138- reg : InlineAsmRegOrRegClass ,
139- late : bool ,
140- expr : Expr <'hir >,
141- },
142- SplitInOut {
143- reg : InlineAsmRegOrRegClass ,
144- late : bool ,
145- in_expr : Expr <'hir >,
146- out_expr : Option <Expr <'hir >>,
147- },
148- Const {
149- anon_const : AnonConst ,
150- },
151- Sym {
152- expr : Expr <'hir >,
153- },
154- }
155- ```
68+ ` InlineAsm ` is represented as an expression in the HIR with the [ ` hir::InlineAsm ` type] [ inline_asm_hir ] .
15669
15770AST lowering is where ` InlineAsmRegOrRegClass ` is converted from ` Symbol ` s to an actual register or
15871register class. If any modifiers are specified for a template string placeholder, these are
15972validated against the set allowed for that operand type. Finally, explicit registers for inputs and
16073outputs are checked for conflicts (same register used for different operands).
16174
75+ [ inline_asm_hir ] : https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/hir/struct.InlineAsm.html
76+
16277## Type checking
16378
16479Each register class has a whitelist of types that it may be used with. After the types of all
@@ -169,152 +84,29 @@ be used for an operand based on the type that was passed into it.
16984
17085## THIR
17186
172- ` InlineAsm ` is represented as an expression in the THIR:
173-
174- ``` rust
175- crate enum ExprKind <'tcx > {
176- // [..]
177- InlineAsm {
178- template : & 'tcx [InlineAsmTemplatePiece ],
179- operands : Box <[InlineAsmOperand <'tcx >]>,
180- options : InlineAsmOptions ,
181- line_spans : & 'tcx [Span ],
182- },
183- }
184- crate enum InlineAsmOperand <'tcx > {
185- In {
186- reg : InlineAsmRegOrRegClass ,
187- expr : ExprId ,
188- },
189- Out {
190- reg : InlineAsmRegOrRegClass ,
191- late : bool ,
192- expr : Option <ExprId >,
193- },
194- InOut {
195- reg : InlineAsmRegOrRegClass ,
196- late : bool ,
197- expr : ExprId ,
198- },
199- SplitInOut {
200- reg : InlineAsmRegOrRegClass ,
201- late : bool ,
202- in_expr : ExprId ,
203- out_expr : Option <ExprId >,
204- },
205- Const {
206- value : & 'tcx Const <'tcx >,
207- span : Span ,
208- },
209- SymFn {
210- expr : ExprId ,
211- },
212- SymStatic {
213- def_id : DefId ,
214- },
215- }
216- ```
87+ ` InlineAsm ` is represented as an expression in the THIR with the [ ` InlineAsmExpr ` type] [ inline_asm_thir ] .
21788
21889The only significant change compared to HIR is that ` Sym ` has been lowered to either a ` SymFn `
21990whose ` expr ` is a ` Literal ` ZST of the ` fn ` , or a ` SymStatic ` which points to the ` DefId ` of a
22091` static ` .
22192
93+ [ inline_asm_thir ] : https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/thir/struct.InlineAsmExpr.html
94+
22295## MIR
22396
224- ` InlineAsm ` is represented as a ` Terminator ` in the MIR:
225-
226- ``` rust
227- pub enum TerminatorKind <'tcx > {
228- // [..]
229-
230- /// Block ends with an inline assembly block. This is a terminator since
231- /// inline assembly is allowed to diverge.
232- InlineAsm {
233- /// The template for the inline assembly, with placeholders.
234- template : & 'tcx [InlineAsmTemplatePiece ],
235-
236- /// The operands for the inline assembly, as `Operand`s or `Place`s.
237- operands : Vec <InlineAsmOperand <'tcx >>,
238-
239- /// Miscellaneous options for the inline assembly.
240- options : InlineAsmOptions ,
241-
242- /// Source spans for each line of the inline assembly code. These are
243- /// used to map assembler errors back to the line in the source code.
244- line_spans : & 'tcx [Span ],
245-
246- /// Destination block after the inline assembly returns, unless it is
247- /// diverging (InlineAsmOptions::NORETURN).
248- destination : Option <BasicBlock >,
249- },
250- }
251-
252- pub enum InlineAsmOperand <'tcx > {
253- In {
254- reg : InlineAsmRegOrRegClass ,
255- value : Operand <'tcx >,
256- },
257- Out {
258- reg : InlineAsmRegOrRegClass ,
259- late : bool ,
260- place : Option <Place <'tcx >>,
261- },
262- InOut {
263- reg : InlineAsmRegOrRegClass ,
264- late : bool ,
265- in_value : Operand <'tcx >,
266- out_place : Option <Place <'tcx >>,
267- },
268- Const {
269- value : Box <Constant <'tcx >>,
270- },
271- SymFn {
272- value : Box <Constant <'tcx >>,
273- },
274- SymStatic {
275- def_id : DefId ,
276- },
277- }
278- ```
97+ ` InlineAsm ` is represented as a ` Terminator ` in the MIR with the [ ` TerminatorKind::InlineAsm ` variant] [ inline_asm_mir ]
27998
28099As part of THIR lowering, ` InOut ` and ` SplitInOut ` operands are lowered to a split form with a
281100separate ` in_value ` and ` out_place ` .
282101
283102Semantically, the ` InlineAsm ` terminator is similar to the ` Call ` terminator except that it has
284103multiple output places where a ` Call ` only has a single return place output.
285104
105+ [ inline_asm_mir ] : https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/mir/enum.TerminatorKind.html#variant.InlineAsm
106+
286107## Codegen
287108
288- Operands are lowered one more time before being passed to LLVM codegen:
289-
290- ``` rust
291- pub enum InlineAsmOperandRef <'tcx , B : BackendTypes + ? Sized > {
292- In {
293- reg : InlineAsmRegOrRegClass ,
294- value : OperandRef <'tcx , B :: Value >,
295- },
296- Out {
297- reg : InlineAsmRegOrRegClass ,
298- late : bool ,
299- place : Option <PlaceRef <'tcx , B :: Value >>,
300- },
301- InOut {
302- reg : InlineAsmRegOrRegClass ,
303- late : bool ,
304- in_value : OperandRef <'tcx , B :: Value >,
305- out_place : Option <PlaceRef <'tcx , B :: Value >>,
306- },
307- Const {
308- string : String ,
309- },
310- SymFn {
311- instance : Instance <'tcx >,
312- },
313- SymStatic {
314- def_id : DefId ,
315- },
316- }
317- ```
109+ Operands are lowered one more time before being passed to LLVM codegen, this is represented by the [ ` InlineAsmOperandRef ` type] [ inline_asm_codegen ] from ` rustc_codegen_ssa ` .
318110
319111The operands are lowered to LLVM operands and constraint codes as follow:
320112- ` out ` and the output part of ` inout ` operands are added first, as required by LLVM. Late output
@@ -339,6 +131,8 @@ Note that LLVM is sometimes rather picky about what types it accepts for certain
339131so we sometimes need to insert conversions to/from a supported type. See the target-specific
340132ISelLowering.cpp files in LLVM for details of what types are supported for each register class.
341133
134+ [ inline_asm_codegen ] : https://doc.rust-lang.org/nightly/nightly-rustc/rustc_codegen_ssa/traits/enum.InlineAsmOperandRef.html
135+
342136## Adding support for new architectures
343137
344138Adding inline assembly support to an architecture is mostly a matter of defining the registers and
0 commit comments