Skip to content

Commit a6b602d

Browse files
committed
Fix inline asm codegen for empty template
1 parent cd96988 commit a6b602d

File tree

1 file changed

+90
-80
lines changed

1 file changed

+90
-80
lines changed

src/inline_asm.rs

Lines changed: 90 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -18,86 +18,96 @@ pub(crate) fn codegen_inline_asm<'tcx>(
1818
) {
1919
// FIXME add .eh_frame unwind info directives
2020

21-
if template[0] == InlineAsmTemplatePiece::String("int $$0x29".to_string()) {
22-
let true_ = fx.bcx.ins().iconst(types::I32, 1);
23-
fx.bcx.ins().trapnz(true_, TrapCode::User(1));
24-
return;
25-
} else if template[0] == InlineAsmTemplatePiece::String("movq %rbx, ".to_string())
26-
&& matches!(
27-
template[1],
28-
InlineAsmTemplatePiece::Placeholder { operand_idx: 0, modifier: Some('r'), span: _ }
29-
)
30-
&& template[2] == InlineAsmTemplatePiece::String("\n".to_string())
31-
&& template[3] == InlineAsmTemplatePiece::String("cpuid".to_string())
32-
&& template[4] == InlineAsmTemplatePiece::String("\n".to_string())
33-
&& template[5] == InlineAsmTemplatePiece::String("xchgq %rbx, ".to_string())
34-
&& matches!(
35-
template[6],
36-
InlineAsmTemplatePiece::Placeholder { operand_idx: 0, modifier: Some('r'), span: _ }
37-
)
38-
{
39-
assert_eq!(operands.len(), 4);
40-
let (leaf, eax_place) = match operands[1] {
41-
InlineAsmOperand::InOut { reg, late: true, ref in_value, out_place } => {
42-
assert_eq!(
43-
reg,
44-
InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::ax))
45-
);
46-
(
47-
crate::base::codegen_operand(fx, in_value).load_scalar(fx),
48-
crate::base::codegen_place(fx, out_place.unwrap()),
49-
)
50-
}
51-
_ => unreachable!(),
52-
};
53-
let ebx_place = match operands[0] {
54-
InlineAsmOperand::Out { reg, late: true, place } => {
55-
assert_eq!(
56-
reg,
57-
InlineAsmRegOrRegClass::RegClass(InlineAsmRegClass::X86(
58-
X86InlineAsmRegClass::reg
59-
))
60-
);
61-
crate::base::codegen_place(fx, place.unwrap())
62-
}
63-
_ => unreachable!(),
64-
};
65-
let (sub_leaf, ecx_place) = match operands[2] {
66-
InlineAsmOperand::InOut { reg, late: true, ref in_value, out_place } => {
67-
assert_eq!(
68-
reg,
69-
InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::cx))
70-
);
71-
(
72-
crate::base::codegen_operand(fx, in_value).load_scalar(fx),
73-
crate::base::codegen_place(fx, out_place.unwrap()),
74-
)
75-
}
76-
_ => unreachable!(),
77-
};
78-
let edx_place = match operands[3] {
79-
InlineAsmOperand::Out { reg, late: true, place } => {
80-
assert_eq!(
81-
reg,
82-
InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::dx))
83-
);
84-
crate::base::codegen_place(fx, place.unwrap())
85-
}
86-
_ => unreachable!(),
87-
};
88-
89-
let (eax, ebx, ecx, edx) = crate::intrinsics::codegen_cpuid_call(fx, leaf, sub_leaf);
90-
91-
eax_place.write_cvalue(fx, CValue::by_val(eax, fx.layout_of(fx.tcx.types.u32)));
92-
ebx_place.write_cvalue(fx, CValue::by_val(ebx, fx.layout_of(fx.tcx.types.u32)));
93-
ecx_place.write_cvalue(fx, CValue::by_val(ecx, fx.layout_of(fx.tcx.types.u32)));
94-
edx_place.write_cvalue(fx, CValue::by_val(edx, fx.layout_of(fx.tcx.types.u32)));
95-
return;
96-
} else if fx.tcx.symbol_name(fx.instance).name.starts_with("___chkstk") {
97-
// ___chkstk, ___chkstk_ms and __alloca are only used on Windows
98-
crate::trap::trap_unimplemented(fx, "Stack probes are not supported");
99-
} else if fx.tcx.symbol_name(fx.instance).name == "__alloca" {
100-
crate::trap::trap_unimplemented(fx, "Alloca is not supported");
21+
if !template.is_empty() {
22+
if template[0] == InlineAsmTemplatePiece::String("int $$0x29".to_string()) {
23+
let true_ = fx.bcx.ins().iconst(types::I32, 1);
24+
fx.bcx.ins().trapnz(true_, TrapCode::User(1));
25+
return;
26+
} else if template[0] == InlineAsmTemplatePiece::String("movq %rbx, ".to_string())
27+
&& matches!(
28+
template[1],
29+
InlineAsmTemplatePiece::Placeholder {
30+
operand_idx: 0,
31+
modifier: Some('r'),
32+
span: _
33+
}
34+
)
35+
&& template[2] == InlineAsmTemplatePiece::String("\n".to_string())
36+
&& template[3] == InlineAsmTemplatePiece::String("cpuid".to_string())
37+
&& template[4] == InlineAsmTemplatePiece::String("\n".to_string())
38+
&& template[5] == InlineAsmTemplatePiece::String("xchgq %rbx, ".to_string())
39+
&& matches!(
40+
template[6],
41+
InlineAsmTemplatePiece::Placeholder {
42+
operand_idx: 0,
43+
modifier: Some('r'),
44+
span: _
45+
}
46+
)
47+
{
48+
assert_eq!(operands.len(), 4);
49+
let (leaf, eax_place) = match operands[1] {
50+
InlineAsmOperand::InOut { reg, late: true, ref in_value, out_place } => {
51+
assert_eq!(
52+
reg,
53+
InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::ax))
54+
);
55+
(
56+
crate::base::codegen_operand(fx, in_value).load_scalar(fx),
57+
crate::base::codegen_place(fx, out_place.unwrap()),
58+
)
59+
}
60+
_ => unreachable!(),
61+
};
62+
let ebx_place = match operands[0] {
63+
InlineAsmOperand::Out { reg, late: true, place } => {
64+
assert_eq!(
65+
reg,
66+
InlineAsmRegOrRegClass::RegClass(InlineAsmRegClass::X86(
67+
X86InlineAsmRegClass::reg
68+
))
69+
);
70+
crate::base::codegen_place(fx, place.unwrap())
71+
}
72+
_ => unreachable!(),
73+
};
74+
let (sub_leaf, ecx_place) = match operands[2] {
75+
InlineAsmOperand::InOut { reg, late: true, ref in_value, out_place } => {
76+
assert_eq!(
77+
reg,
78+
InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::cx))
79+
);
80+
(
81+
crate::base::codegen_operand(fx, in_value).load_scalar(fx),
82+
crate::base::codegen_place(fx, out_place.unwrap()),
83+
)
84+
}
85+
_ => unreachable!(),
86+
};
87+
let edx_place = match operands[3] {
88+
InlineAsmOperand::Out { reg, late: true, place } => {
89+
assert_eq!(
90+
reg,
91+
InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::dx))
92+
);
93+
crate::base::codegen_place(fx, place.unwrap())
94+
}
95+
_ => unreachable!(),
96+
};
97+
98+
let (eax, ebx, ecx, edx) = crate::intrinsics::codegen_cpuid_call(fx, leaf, sub_leaf);
99+
100+
eax_place.write_cvalue(fx, CValue::by_val(eax, fx.layout_of(fx.tcx.types.u32)));
101+
ebx_place.write_cvalue(fx, CValue::by_val(ebx, fx.layout_of(fx.tcx.types.u32)));
102+
ecx_place.write_cvalue(fx, CValue::by_val(ecx, fx.layout_of(fx.tcx.types.u32)));
103+
edx_place.write_cvalue(fx, CValue::by_val(edx, fx.layout_of(fx.tcx.types.u32)));
104+
return;
105+
} else if fx.tcx.symbol_name(fx.instance).name.starts_with("___chkstk") {
106+
// ___chkstk, ___chkstk_ms and __alloca are only used on Windows
107+
crate::trap::trap_unimplemented(fx, "Stack probes are not supported");
108+
} else if fx.tcx.symbol_name(fx.instance).name == "__alloca" {
109+
crate::trap::trap_unimplemented(fx, "Alloca is not supported");
110+
}
101111
}
102112

103113
let mut inputs = Vec::new();

0 commit comments

Comments
 (0)