Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 1662702

Browse files
committed
Work around new asm! usage in measureme
This is necessary to fix rustc bootstraps
1 parent 523f0db commit 1662702

File tree

1 file changed

+119
-37
lines changed

1 file changed

+119
-37
lines changed

src/inline_asm.rs

Lines changed: 119 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,14 @@ pub(crate) fn codegen_inline_asm<'tcx>(
2020
// FIXME add .eh_frame unwind info directives
2121

2222
if !template.is_empty() {
23+
// Used by panic_abort
2324
if template[0] == InlineAsmTemplatePiece::String("int $$0x29".to_string()) {
2425
fx.bcx.ins().trap(TrapCode::User(1));
2526
return;
26-
} else if template[0] == InlineAsmTemplatePiece::String("movq %rbx, ".to_string())
27+
}
28+
29+
// Used by stdarch
30+
if template[0] == InlineAsmTemplatePiece::String("movq %rbx, ".to_string())
2731
&& matches!(
2832
template[1],
2933
InlineAsmTemplatePiece::Placeholder {
@@ -47,51 +51,46 @@ pub(crate) fn codegen_inline_asm<'tcx>(
4751
{
4852
assert_eq!(operands.len(), 4);
4953
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-
}
54+
InlineAsmOperand::InOut {
55+
reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::ax)),
56+
late: true,
57+
ref in_value,
58+
out_place: Some(out_place),
59+
} => (
60+
crate::base::codegen_operand(fx, in_value).load_scalar(fx),
61+
crate::base::codegen_place(fx, out_place),
62+
),
6063
_ => unreachable!(),
6164
};
6265
let ebx_place = match operands[0] {
63-
InlineAsmOperand::Out { reg, late: true, place } => {
64-
assert_eq!(
65-
reg,
66+
InlineAsmOperand::Out {
67+
reg:
6668
InlineAsmRegOrRegClass::RegClass(InlineAsmRegClass::X86(
67-
X86InlineAsmRegClass::reg
68-
))
69-
);
70-
crate::base::codegen_place(fx, place.unwrap())
71-
}
69+
X86InlineAsmRegClass::reg,
70+
)),
71+
late: true,
72+
place: Some(place),
73+
} => crate::base::codegen_place(fx, place),
7274
_ => unreachable!(),
7375
};
7476
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-
}
77+
InlineAsmOperand::InOut {
78+
reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::cx)),
79+
late: true,
80+
ref in_value,
81+
out_place: Some(out_place),
82+
} => (
83+
crate::base::codegen_operand(fx, in_value).load_scalar(fx),
84+
crate::base::codegen_place(fx, out_place),
85+
),
8586
_ => unreachable!(),
8687
};
8788
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-
}
89+
InlineAsmOperand::Out {
90+
reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::dx)),
91+
late: true,
92+
place: Some(place),
93+
} => crate::base::codegen_place(fx, place),
9594
_ => unreachable!(),
9695
};
9796

@@ -104,14 +103,97 @@ pub(crate) fn codegen_inline_asm<'tcx>(
104103
let destination_block = fx.get_block(destination.unwrap());
105104
fx.bcx.ins().jump(destination_block, &[]);
106105
return;
107-
} else if fx.tcx.symbol_name(fx.instance).name.starts_with("___chkstk") {
106+
}
107+
108+
// Used by compiler-builtins
109+
if fx.tcx.symbol_name(fx.instance).name.starts_with("___chkstk") {
108110
// ___chkstk, ___chkstk_ms and __alloca are only used on Windows
109111
crate::trap::trap_unimplemented(fx, "Stack probes are not supported");
110112
return;
111113
} else if fx.tcx.symbol_name(fx.instance).name == "__alloca" {
112114
crate::trap::trap_unimplemented(fx, "Alloca is not supported");
113115
return;
114116
}
117+
118+
// Used by measureme
119+
if template[0] == InlineAsmTemplatePiece::String("xor %eax, %eax".to_string())
120+
&& template[1] == InlineAsmTemplatePiece::String("\n".to_string())
121+
&& template[2] == InlineAsmTemplatePiece::String("mov %rbx, ".to_string())
122+
&& matches!(
123+
template[3],
124+
InlineAsmTemplatePiece::Placeholder {
125+
operand_idx: 0,
126+
modifier: Some('r'),
127+
span: _
128+
}
129+
)
130+
&& template[4] == InlineAsmTemplatePiece::String("\n".to_string())
131+
&& template[5] == InlineAsmTemplatePiece::String("cpuid".to_string())
132+
&& template[6] == InlineAsmTemplatePiece::String("\n".to_string())
133+
&& template[7] == InlineAsmTemplatePiece::String("mov ".to_string())
134+
&& matches!(
135+
template[8],
136+
InlineAsmTemplatePiece::Placeholder {
137+
operand_idx: 0,
138+
modifier: Some('r'),
139+
span: _
140+
}
141+
)
142+
&& template[9] == InlineAsmTemplatePiece::String(", %rbx".to_string())
143+
{
144+
let destination_block = fx.get_block(destination.unwrap());
145+
fx.bcx.ins().jump(destination_block, &[]);
146+
return;
147+
} else if template[0] == InlineAsmTemplatePiece::String("rdpmc".to_string()) {
148+
// Return zero dummy values for all performance counters
149+
match operands[0] {
150+
InlineAsmOperand::In {
151+
reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::cx)),
152+
value: _,
153+
} => {}
154+
_ => unreachable!(),
155+
};
156+
let lo = match operands[1] {
157+
InlineAsmOperand::Out {
158+
reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::ax)),
159+
late: true,
160+
place: Some(place),
161+
} => crate::base::codegen_place(fx, place),
162+
_ => unreachable!(),
163+
};
164+
let hi = match operands[2] {
165+
InlineAsmOperand::Out {
166+
reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::dx)),
167+
late: true,
168+
place: Some(place),
169+
} => crate::base::codegen_place(fx, place),
170+
_ => unreachable!(),
171+
};
172+
173+
let u32_layout = fx.layout_of(fx.tcx.types.u32);
174+
let zero = fx.bcx.ins().iconst(types::I32, 0);
175+
lo.write_cvalue(fx, CValue::by_val(zero, u32_layout));
176+
hi.write_cvalue(fx, CValue::by_val(zero, u32_layout));
177+
178+
let destination_block = fx.get_block(destination.unwrap());
179+
fx.bcx.ins().jump(destination_block, &[]);
180+
return;
181+
} else if template[0] == InlineAsmTemplatePiece::String("lock xadd ".to_string())
182+
&& matches!(
183+
template[1],
184+
InlineAsmTemplatePiece::Placeholder { operand_idx: 1, modifier: None, span: _ }
185+
)
186+
&& template[2] == InlineAsmTemplatePiece::String(", (".to_string())
187+
&& matches!(
188+
template[3],
189+
InlineAsmTemplatePiece::Placeholder { operand_idx: 0, modifier: None, span: _ }
190+
)
191+
&& template[4] == InlineAsmTemplatePiece::String(")".to_string())
192+
{
193+
let destination_block = fx.get_block(destination.unwrap());
194+
fx.bcx.ins().jump(destination_block, &[]);
195+
return;
196+
}
115197
}
116198

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

0 commit comments

Comments
 (0)