3 /// Emulates a subset of the cpuid call.
5 /// This emulates an intel cpu with sse and sse2 support, but which doesn't support anything else.
6 pub(crate) fn codegen_cpuid_call<'tcx>(
7 fx: &mut FunctionCx<'_, 'tcx, impl Backend>,
10 ) -> (Value, Value, Value, Value) {
11 let leaf_0 = fx.bcx.create_block();
12 let leaf_1 = fx.bcx.create_block();
13 let leaf_8000_0000 = fx.bcx.create_block();
14 let leaf_8000_0001 = fx.bcx.create_block();
15 let unsupported_leaf = fx.bcx.create_block();
17 let dest = fx.bcx.create_block();
18 let eax = fx.bcx.append_block_param(dest, types::I32);
19 let ebx = fx.bcx.append_block_param(dest, types::I32);
20 let ecx = fx.bcx.append_block_param(dest, types::I32);
21 let edx = fx.bcx.append_block_param(dest, types::I32);
23 let mut switch = cranelift_frontend::Switch::new();
24 switch.set_entry(0, leaf_0);
25 switch.set_entry(1, leaf_1);
26 switch.set_entry(0x8000_0000, leaf_8000_0000);
27 switch.set_entry(0x8000_0001, leaf_8000_0001);
28 switch.emit(&mut fx.bcx, leaf, unsupported_leaf);
30 fx.bcx.switch_to_block(leaf_0);
31 let max_basic_leaf = fx.bcx.ins().iconst(types::I32, 1);
32 let vend0 = fx.bcx.ins().iconst(types::I32, i64::from(u32::from_le_bytes(*b"Genu")));
33 let vend2 = fx.bcx.ins().iconst(types::I32, i64::from(u32::from_le_bytes(*b"ineI")));
34 let vend1 = fx.bcx.ins().iconst(types::I32, i64::from(u32::from_le_bytes(*b"ntel")));
35 fx.bcx.ins().jump(dest, &[max_basic_leaf, vend0, vend1, vend2]);
37 fx.bcx.switch_to_block(leaf_1);
38 let cpu_signature = fx.bcx.ins().iconst(types::I32, 0);
39 let additional_information = fx.bcx.ins().iconst(types::I32, 0);
40 let ecx_features = fx.bcx.ins().iconst(
44 let edx_features = fx.bcx.ins().iconst(
46 1 << 25 /* sse */ | 1 << 26 /* sse2 */,
48 fx.bcx.ins().jump(dest, &[cpu_signature, additional_information, ecx_features, edx_features]);
50 fx.bcx.switch_to_block(leaf_8000_0000);
51 let extended_max_basic_leaf = fx.bcx.ins().iconst(types::I32, 0);
52 let zero = fx.bcx.ins().iconst(types::I32, 0);
53 fx.bcx.ins().jump(dest, &[extended_max_basic_leaf, zero, zero, zero]);
55 fx.bcx.switch_to_block(leaf_8000_0001);
56 let zero = fx.bcx.ins().iconst(types::I32, 0);
57 let proc_info_ecx = fx.bcx.ins().iconst(types::I32, 0);
58 let proc_info_edx = fx.bcx.ins().iconst(types::I32, 0);
59 fx.bcx.ins().jump(dest, &[zero, zero, proc_info_ecx, proc_info_edx]);
61 fx.bcx.switch_to_block(unsupported_leaf);
62 crate::trap::trap_unreachable(fx, "__cpuid_count arch intrinsic doesn't yet support specified leaf");
64 fx.bcx.switch_to_block(dest);