Add support for const operands and options to global_asm!
On x86, the default syntax is also switched to Intel to match asm!
This commit is contained in:
parent
952c5732c2
commit
5918ee4317
36 changed files with 928 additions and 800 deletions
|
@ -1164,9 +1164,9 @@ impl<'a> State<'a> {
|
|||
self.print_foreign_mod(nmod, &item.attrs);
|
||||
self.bclose(item.span);
|
||||
}
|
||||
ast::ItemKind::GlobalAsm(ref ga) => {
|
||||
ast::ItemKind::GlobalAsm(ref asm) => {
|
||||
self.head(visibility_qualified(&item.vis, "global_asm!"));
|
||||
self.s.word(ga.asm.to_string());
|
||||
self.print_inline_asm(asm);
|
||||
self.end();
|
||||
}
|
||||
ast::ItemKind::TyAlias(box ast::TyAliasKind(def, ref generics, ref bounds, ref ty)) => {
|
||||
|
@ -2066,117 +2066,8 @@ impl<'a> State<'a> {
|
|||
}
|
||||
}
|
||||
ast::ExprKind::InlineAsm(ref a) => {
|
||||
enum AsmArg<'a> {
|
||||
Template(String),
|
||||
Operand(&'a InlineAsmOperand),
|
||||
Options(InlineAsmOptions),
|
||||
}
|
||||
|
||||
let mut args = vec![];
|
||||
args.push(AsmArg::Template(InlineAsmTemplatePiece::to_string(&a.template)));
|
||||
args.extend(a.operands.iter().map(|(o, _)| AsmArg::Operand(o)));
|
||||
if !a.options.is_empty() {
|
||||
args.push(AsmArg::Options(a.options));
|
||||
}
|
||||
|
||||
self.word("asm!");
|
||||
self.popen();
|
||||
self.commasep(Consistent, &args, |s, arg| match arg {
|
||||
AsmArg::Template(template) => s.print_string(&template, ast::StrStyle::Cooked),
|
||||
AsmArg::Operand(op) => {
|
||||
let print_reg_or_class = |s: &mut Self, r: &InlineAsmRegOrRegClass| match r
|
||||
{
|
||||
InlineAsmRegOrRegClass::Reg(r) => {
|
||||
s.print_symbol(*r, ast::StrStyle::Cooked)
|
||||
}
|
||||
InlineAsmRegOrRegClass::RegClass(r) => s.word(r.to_string()),
|
||||
};
|
||||
match op {
|
||||
InlineAsmOperand::In { reg, expr } => {
|
||||
s.word("in");
|
||||
s.popen();
|
||||
print_reg_or_class(s, reg);
|
||||
s.pclose();
|
||||
s.space();
|
||||
s.print_expr(expr);
|
||||
}
|
||||
InlineAsmOperand::Out { reg, late, expr } => {
|
||||
s.word(if *late { "lateout" } else { "out" });
|
||||
s.popen();
|
||||
print_reg_or_class(s, reg);
|
||||
s.pclose();
|
||||
s.space();
|
||||
match expr {
|
||||
Some(expr) => s.print_expr(expr),
|
||||
None => s.word("_"),
|
||||
}
|
||||
}
|
||||
InlineAsmOperand::InOut { reg, late, expr } => {
|
||||
s.word(if *late { "inlateout" } else { "inout" });
|
||||
s.popen();
|
||||
print_reg_or_class(s, reg);
|
||||
s.pclose();
|
||||
s.space();
|
||||
s.print_expr(expr);
|
||||
}
|
||||
InlineAsmOperand::SplitInOut { reg, late, in_expr, out_expr } => {
|
||||
s.word(if *late { "inlateout" } else { "inout" });
|
||||
s.popen();
|
||||
print_reg_or_class(s, reg);
|
||||
s.pclose();
|
||||
s.space();
|
||||
s.print_expr(in_expr);
|
||||
s.space();
|
||||
s.word_space("=>");
|
||||
match out_expr {
|
||||
Some(out_expr) => s.print_expr(out_expr),
|
||||
None => s.word("_"),
|
||||
}
|
||||
}
|
||||
InlineAsmOperand::Const { anon_const } => {
|
||||
s.word("const");
|
||||
s.space();
|
||||
s.print_expr(&anon_const.value);
|
||||
}
|
||||
InlineAsmOperand::Sym { expr } => {
|
||||
s.word("sym");
|
||||
s.space();
|
||||
s.print_expr(expr);
|
||||
}
|
||||
}
|
||||
}
|
||||
AsmArg::Options(opts) => {
|
||||
s.word("options");
|
||||
s.popen();
|
||||
let mut options = vec![];
|
||||
if opts.contains(InlineAsmOptions::PURE) {
|
||||
options.push("pure");
|
||||
}
|
||||
if opts.contains(InlineAsmOptions::NOMEM) {
|
||||
options.push("nomem");
|
||||
}
|
||||
if opts.contains(InlineAsmOptions::READONLY) {
|
||||
options.push("readonly");
|
||||
}
|
||||
if opts.contains(InlineAsmOptions::PRESERVES_FLAGS) {
|
||||
options.push("preserves_flags");
|
||||
}
|
||||
if opts.contains(InlineAsmOptions::NORETURN) {
|
||||
options.push("noreturn");
|
||||
}
|
||||
if opts.contains(InlineAsmOptions::NOSTACK) {
|
||||
options.push("nostack");
|
||||
}
|
||||
if opts.contains(InlineAsmOptions::ATT_SYNTAX) {
|
||||
options.push("att_syntax");
|
||||
}
|
||||
s.commasep(Inconsistent, &options, |s, &opt| {
|
||||
s.word(opt);
|
||||
});
|
||||
s.pclose();
|
||||
}
|
||||
});
|
||||
self.pclose();
|
||||
self.print_inline_asm(a);
|
||||
}
|
||||
ast::ExprKind::LlvmInlineAsm(ref a) => {
|
||||
self.s.word("llvm_asm!");
|
||||
|
@ -2267,6 +2158,116 @@ impl<'a> State<'a> {
|
|||
self.end();
|
||||
}
|
||||
|
||||
fn print_inline_asm(&mut self, asm: &ast::InlineAsm) {
|
||||
enum AsmArg<'a> {
|
||||
Template(String),
|
||||
Operand(&'a InlineAsmOperand),
|
||||
Options(InlineAsmOptions),
|
||||
}
|
||||
|
||||
let mut args = vec![];
|
||||
args.push(AsmArg::Template(InlineAsmTemplatePiece::to_string(&asm.template)));
|
||||
args.extend(asm.operands.iter().map(|(o, _)| AsmArg::Operand(o)));
|
||||
if !asm.options.is_empty() {
|
||||
args.push(AsmArg::Options(asm.options));
|
||||
}
|
||||
|
||||
self.popen();
|
||||
self.commasep(Consistent, &args, |s, arg| match arg {
|
||||
AsmArg::Template(template) => s.print_string(&template, ast::StrStyle::Cooked),
|
||||
AsmArg::Operand(op) => {
|
||||
let print_reg_or_class = |s: &mut Self, r: &InlineAsmRegOrRegClass| match r {
|
||||
InlineAsmRegOrRegClass::Reg(r) => s.print_symbol(*r, ast::StrStyle::Cooked),
|
||||
InlineAsmRegOrRegClass::RegClass(r) => s.word(r.to_string()),
|
||||
};
|
||||
match op {
|
||||
InlineAsmOperand::In { reg, expr } => {
|
||||
s.word("in");
|
||||
s.popen();
|
||||
print_reg_or_class(s, reg);
|
||||
s.pclose();
|
||||
s.space();
|
||||
s.print_expr(expr);
|
||||
}
|
||||
InlineAsmOperand::Out { reg, late, expr } => {
|
||||
s.word(if *late { "lateout" } else { "out" });
|
||||
s.popen();
|
||||
print_reg_or_class(s, reg);
|
||||
s.pclose();
|
||||
s.space();
|
||||
match expr {
|
||||
Some(expr) => s.print_expr(expr),
|
||||
None => s.word("_"),
|
||||
}
|
||||
}
|
||||
InlineAsmOperand::InOut { reg, late, expr } => {
|
||||
s.word(if *late { "inlateout" } else { "inout" });
|
||||
s.popen();
|
||||
print_reg_or_class(s, reg);
|
||||
s.pclose();
|
||||
s.space();
|
||||
s.print_expr(expr);
|
||||
}
|
||||
InlineAsmOperand::SplitInOut { reg, late, in_expr, out_expr } => {
|
||||
s.word(if *late { "inlateout" } else { "inout" });
|
||||
s.popen();
|
||||
print_reg_or_class(s, reg);
|
||||
s.pclose();
|
||||
s.space();
|
||||
s.print_expr(in_expr);
|
||||
s.space();
|
||||
s.word_space("=>");
|
||||
match out_expr {
|
||||
Some(out_expr) => s.print_expr(out_expr),
|
||||
None => s.word("_"),
|
||||
}
|
||||
}
|
||||
InlineAsmOperand::Const { anon_const } => {
|
||||
s.word("const");
|
||||
s.space();
|
||||
s.print_expr(&anon_const.value);
|
||||
}
|
||||
InlineAsmOperand::Sym { expr } => {
|
||||
s.word("sym");
|
||||
s.space();
|
||||
s.print_expr(expr);
|
||||
}
|
||||
}
|
||||
}
|
||||
AsmArg::Options(opts) => {
|
||||
s.word("options");
|
||||
s.popen();
|
||||
let mut options = vec![];
|
||||
if opts.contains(InlineAsmOptions::PURE) {
|
||||
options.push("pure");
|
||||
}
|
||||
if opts.contains(InlineAsmOptions::NOMEM) {
|
||||
options.push("nomem");
|
||||
}
|
||||
if opts.contains(InlineAsmOptions::READONLY) {
|
||||
options.push("readonly");
|
||||
}
|
||||
if opts.contains(InlineAsmOptions::PRESERVES_FLAGS) {
|
||||
options.push("preserves_flags");
|
||||
}
|
||||
if opts.contains(InlineAsmOptions::NORETURN) {
|
||||
options.push("noreturn");
|
||||
}
|
||||
if opts.contains(InlineAsmOptions::NOSTACK) {
|
||||
options.push("nostack");
|
||||
}
|
||||
if opts.contains(InlineAsmOptions::ATT_SYNTAX) {
|
||||
options.push("att_syntax");
|
||||
}
|
||||
s.commasep(Inconsistent, &options, |s, &opt| {
|
||||
s.word(opt);
|
||||
});
|
||||
s.pclose();
|
||||
}
|
||||
});
|
||||
self.pclose();
|
||||
}
|
||||
|
||||
crate fn print_local_decl(&mut self, loc: &ast::Local) {
|
||||
self.print_pat(&loc.pat);
|
||||
if let Some(ref ty) = loc.ty {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue