Skip to content

Commit d5b1501

Browse files
committed
Add asm! to HIR
1 parent a0adf53 commit d5b1501

File tree

3 files changed

+177
-0
lines changed

3 files changed

+177
-0
lines changed

src/librustc_hir/hir.rs

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ use rustc_macros::HashStable_Generic;
1515
use rustc_span::source_map::{SourceMap, Spanned};
1616
use rustc_span::symbol::{kw, sym, Ident, Symbol};
1717
use rustc_span::{MultiSpan, Span, DUMMY_SP};
18+
use rustc_target::asm::{InlineAsmOptions, InlineAsmRegOrRegClass, InlineAsmTemplatePiece};
1819
use rustc_target::spec::abi::Abi;
1920

2021
use smallvec::SmallVec;
@@ -1391,6 +1392,7 @@ impl Expr<'_> {
13911392
ExprKind::Break(..) => ExprPrecedence::Break,
13921393
ExprKind::Continue(..) => ExprPrecedence::Continue,
13931394
ExprKind::Ret(..) => ExprPrecedence::Ret,
1395+
ExprKind::InlineAsm(..) => ExprPrecedence::InlineAsm,
13941396
ExprKind::LlvmInlineAsm(..) => ExprPrecedence::InlineAsm,
13951397
ExprKind::Struct(..) => ExprPrecedence::Struct,
13961398
ExprKind::Repeat(..) => ExprPrecedence::Repeat,
@@ -1446,6 +1448,7 @@ impl Expr<'_> {
14461448
| ExprKind::Ret(..)
14471449
| ExprKind::Loop(..)
14481450
| ExprKind::Assign(..)
1451+
| ExprKind::InlineAsm(..)
14491452
| ExprKind::LlvmInlineAsm(..)
14501453
| ExprKind::AssignOp(..)
14511454
| ExprKind::Lit(_)
@@ -1622,6 +1625,8 @@ pub enum ExprKind<'hir> {
16221625
/// A `return`, with an optional value to be returned.
16231626
Ret(Option<&'hir Expr<'hir>>),
16241627

1628+
/// Inline assembly (from `asm!`), with its outputs and inputs.
1629+
InlineAsm(&'hir InlineAsm<'hir>),
16251630
/// Inline assembly (from `llvm_asm!`), with its outputs and inputs.
16261631
LlvmInlineAsm(&'hir LlvmInlineAsm<'hir>),
16271632

@@ -2054,6 +2059,55 @@ pub enum TyKind<'hir> {
20542059
Err,
20552060
}
20562061

2062+
#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
2063+
pub enum InlineAsmOperand<'hir> {
2064+
In {
2065+
reg: InlineAsmRegOrRegClass,
2066+
expr: Expr<'hir>,
2067+
},
2068+
Out {
2069+
reg: InlineAsmRegOrRegClass,
2070+
late: bool,
2071+
expr: Option<Expr<'hir>>,
2072+
},
2073+
InOut {
2074+
reg: InlineAsmRegOrRegClass,
2075+
late: bool,
2076+
expr: Expr<'hir>,
2077+
},
2078+
SplitInOut {
2079+
reg: InlineAsmRegOrRegClass,
2080+
late: bool,
2081+
in_expr: Expr<'hir>,
2082+
out_expr: Option<Expr<'hir>>,
2083+
},
2084+
Const {
2085+
expr: Expr<'hir>,
2086+
},
2087+
Sym {
2088+
expr: Expr<'hir>,
2089+
},
2090+
}
2091+
2092+
impl<'hir> InlineAsmOperand<'hir> {
2093+
pub fn reg(&self) -> Option<InlineAsmRegOrRegClass> {
2094+
match *self {
2095+
Self::In { reg, .. }
2096+
| Self::Out { reg, .. }
2097+
| Self::InOut { reg, .. }
2098+
| Self::SplitInOut { reg, .. } => Some(reg),
2099+
Self::Const { .. } | Self::Sym { .. } => None,
2100+
}
2101+
}
2102+
}
2103+
2104+
#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
2105+
pub struct InlineAsm<'hir> {
2106+
pub template: &'hir [InlineAsmTemplatePiece],
2107+
pub operands: &'hir [InlineAsmOperand<'hir>],
2108+
pub options: InlineAsmOptions,
2109+
}
2110+
20572111
#[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug, HashStable_Generic, PartialEq)]
20582112
pub struct LlvmInlineAsmOutput {
20592113
pub constraint: Symbol,

src/librustc_hir/intravisit.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1157,6 +1157,27 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr<'v>)
11571157
ExprKind::Ret(ref optional_expression) => {
11581158
walk_list!(visitor, visit_expr, optional_expression);
11591159
}
1160+
ExprKind::InlineAsm(ref asm) => {
1161+
for op in asm.operands {
1162+
match op {
1163+
InlineAsmOperand::In { expr, .. }
1164+
| InlineAsmOperand::InOut { expr, .. }
1165+
| InlineAsmOperand::Const { expr, .. }
1166+
| InlineAsmOperand::Sym { expr, .. } => visitor.visit_expr(expr),
1167+
InlineAsmOperand::Out { expr, .. } => {
1168+
if let Some(expr) = expr {
1169+
visitor.visit_expr(expr);
1170+
}
1171+
}
1172+
InlineAsmOperand::SplitInOut { in_expr, out_expr, .. } => {
1173+
visitor.visit_expr(in_expr);
1174+
if let Some(out_expr) = out_expr {
1175+
visitor.visit_expr(out_expr);
1176+
}
1177+
}
1178+
}
1179+
}
1180+
}
11601181
ExprKind::LlvmInlineAsm(ref asm) => {
11611182
walk_list!(visitor, visit_expr, asm.outputs_exprs);
11621183
walk_list!(visitor, visit_expr, asm.inputs_exprs);

src/librustc_hir_pretty/lib.rs

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use rustc_hir::{GenericBound, PatKind, RangeEnd, TraitBoundModifier};
1212
use rustc_span::source_map::{SourceMap, Spanned};
1313
use rustc_span::symbol::{kw, Ident, IdentPrinter, Symbol};
1414
use rustc_span::{self, BytePos, FileName};
15+
use rustc_target::asm::{InlineAsmOptions, InlineAsmTemplatePiece};
1516
use rustc_target::spec::abi::Abi;
1617

1718
use std::borrow::Cow;
@@ -1409,6 +1410,107 @@ impl<'a> State<'a> {
14091410
self.print_expr_maybe_paren(&expr, parser::PREC_JUMP);
14101411
}
14111412
}
1413+
hir::ExprKind::InlineAsm(ref a) => {
1414+
enum AsmArg<'a> {
1415+
Template(String),
1416+
Operand(&'a hir::InlineAsmOperand<'a>),
1417+
Options(InlineAsmOptions),
1418+
}
1419+
1420+
let mut args = vec![];
1421+
args.push(AsmArg::Template(InlineAsmTemplatePiece::to_string(&a.template)));
1422+
args.extend(a.operands.iter().map(|o| AsmArg::Operand(o)));
1423+
if !a.options.is_empty() {
1424+
args.push(AsmArg::Options(a.options));
1425+
}
1426+
1427+
self.word("asm!");
1428+
self.popen();
1429+
self.commasep(Consistent, &args, |s, arg| match arg {
1430+
AsmArg::Template(template) => s.print_string(&template, ast::StrStyle::Cooked),
1431+
AsmArg::Operand(op) => match op {
1432+
hir::InlineAsmOperand::In { reg, expr } => {
1433+
s.word("in");
1434+
s.popen();
1435+
s.word(format!("{}", reg));
1436+
s.pclose();
1437+
s.space();
1438+
s.print_expr(expr);
1439+
}
1440+
hir::InlineAsmOperand::Out { reg, late, expr } => {
1441+
s.word(if *late { "lateout" } else { "out" });
1442+
s.popen();
1443+
s.word(format!("{}", reg));
1444+
s.pclose();
1445+
s.space();
1446+
match expr {
1447+
Some(expr) => s.print_expr(expr),
1448+
None => s.word("_"),
1449+
}
1450+
}
1451+
hir::InlineAsmOperand::InOut { reg, late, expr } => {
1452+
s.word(if *late { "inlateout" } else { "inout" });
1453+
s.popen();
1454+
s.word(format!("{}", reg));
1455+
s.pclose();
1456+
s.space();
1457+
s.print_expr(expr);
1458+
}
1459+
hir::InlineAsmOperand::SplitInOut { reg, late, in_expr, out_expr } => {
1460+
s.word(if *late { "inlateout" } else { "inout" });
1461+
s.popen();
1462+
s.word(format!("{}", reg));
1463+
s.pclose();
1464+
s.space();
1465+
s.print_expr(in_expr);
1466+
s.space();
1467+
s.word_space("=>");
1468+
match out_expr {
1469+
Some(out_expr) => s.print_expr(out_expr),
1470+
None => s.word("_"),
1471+
}
1472+
}
1473+
hir::InlineAsmOperand::Const { expr } => {
1474+
s.word("const");
1475+
s.space();
1476+
s.print_expr(expr);
1477+
}
1478+
hir::InlineAsmOperand::Sym { expr } => {
1479+
s.word("sym");
1480+
s.space();
1481+
s.print_expr(expr);
1482+
}
1483+
},
1484+
AsmArg::Options(opts) => {
1485+
s.word("options");
1486+
s.popen();
1487+
let mut options = vec![];
1488+
if opts.contains(InlineAsmOptions::PURE) {
1489+
options.push("pure");
1490+
}
1491+
if opts.contains(InlineAsmOptions::NOMEM) {
1492+
options.push("nomem");
1493+
}
1494+
if opts.contains(InlineAsmOptions::READONLY) {
1495+
options.push("readonly");
1496+
}
1497+
if opts.contains(InlineAsmOptions::PRESERVES_FLAGS) {
1498+
options.push("preserves_flags");
1499+
}
1500+
if opts.contains(InlineAsmOptions::NORETURN) {
1501+
options.push("noreturn");
1502+
}
1503+
if opts.contains(InlineAsmOptions::NOSTACK) {
1504+
options.push("nostack");
1505+
}
1506+
s.commasep(Inconsistent, &options, |s, &opt| {
1507+
s.word(opt);
1508+
});
1509+
s.pclose();
1510+
}
1511+
});
1512+
self.pclose();
1513+
}
14121514
hir::ExprKind::LlvmInlineAsm(ref a) => {
14131515
let i = &a.inner;
14141516
self.s.word("llvm_asm!");

0 commit comments

Comments
 (0)