#[derive(Clone)]
pub struct Flags {
bytes: [u8; 6],
}
impl Flags {
#[allow(unused_variables)]
pub fn new(builder: Builder) -> Self {
let bvec = builder.state_for("shared");
let mut shared = Self { bytes: [0; 6] };
debug_assert_eq!(bvec.len(), 6);
shared.bytes[0..6].copy_from_slice(&bvec);
shared
}
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub enum OptLevel {
None,
Speed,
SpeedAndSize,
}
impl fmt::Display for OptLevel {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_str(match *self {
Self::None => "none",
Self::Speed => "speed",
Self::SpeedAndSize => "speed_and_size",
})
}
}
impl str::FromStr for OptLevel {
type Err = ();
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"none" => Ok(Self::None),
"speed" => Ok(Self::Speed),
"speed_and_size" => Ok(Self::SpeedAndSize),
_ => Err(()),
}
}
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub enum LibcallCallConv {
IsaDefault,
Fast,
Cold,
SystemV,
WindowsFastcall,
BaldrdashSystemV,
BaldrdashWindows,
Probestack,
}
impl fmt::Display for LibcallCallConv {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_str(match *self {
Self::IsaDefault => "isa_default",
Self::Fast => "fast",
Self::Cold => "cold",
Self::SystemV => "system_v",
Self::WindowsFastcall => "windows_fastcall",
Self::BaldrdashSystemV => "baldrdash_system_v",
Self::BaldrdashWindows => "baldrdash_windows",
Self::Probestack => "probestack",
})
}
}
impl str::FromStr for LibcallCallConv {
type Err = ();
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"isa_default" => Ok(Self::IsaDefault),
"fast" => Ok(Self::Fast),
"cold" => Ok(Self::Cold),
"system_v" => Ok(Self::SystemV),
"windows_fastcall" => Ok(Self::WindowsFastcall),
"baldrdash_system_v" => Ok(Self::BaldrdashSystemV),
"baldrdash_windows" => Ok(Self::BaldrdashWindows),
"probestack" => Ok(Self::Probestack),
_ => Err(()),
}
}
}
#[allow(dead_code)]
impl Flags {
pub fn predicate_view(&self) -> crate::settings::PredicateView {
crate::settings::PredicateView::new(&self.bytes[4..])
}
fn numbered_predicate(&self, p: usize) -> bool {
self.bytes[4 + p / 8] & (1 << (p % 8)) != 0
}
pub fn opt_level(&self) -> OptLevel {
match self.bytes[0] {
0 => {
OptLevel::None
}
1 => {
OptLevel::Speed
}
2 => {
OptLevel::SpeedAndSize
}
_ => {
panic!("Invalid enum value")
}
}
}
pub fn libcall_call_conv(&self) -> LibcallCallConv {
match self.bytes[1] {
5 => {
LibcallCallConv::BaldrdashSystemV
}
6 => {
LibcallCallConv::BaldrdashWindows
}
2 => {
LibcallCallConv::Cold
}
1 => {
LibcallCallConv::Fast
}
0 => {
LibcallCallConv::IsaDefault
}
7 => {
LibcallCallConv::Probestack
}
3 => {
LibcallCallConv::SystemV
}
4 => {
LibcallCallConv::WindowsFastcall
}
_ => {
panic!("Invalid enum value")
}
}
}
pub fn baldrdash_prologue_words(&self) -> u8 {
self.bytes[2]
}
pub fn probestack_size_log2(&self) -> u8 {
self.bytes[3]
}
pub fn enable_verifier(&self) -> bool {
self.numbered_predicate(0)
}
pub fn is_pic(&self) -> bool {
self.numbered_predicate(1)
}
pub fn use_colocated_libcalls(&self) -> bool {
self.numbered_predicate(2)
}
pub fn avoid_div_traps(&self) -> bool {
self.numbered_predicate(3)
}
pub fn enable_float(&self) -> bool {
self.numbered_predicate(4)
}
pub fn enable_nan_canonicalization(&self) -> bool {
self.numbered_predicate(5)
}
pub fn enable_pinned_reg(&self) -> bool {
self.numbered_predicate(6)
}
pub fn use_pinned_reg_as_heap_base(&self) -> bool {
self.numbered_predicate(7)
}
pub fn enable_simd(&self) -> bool {
self.numbered_predicate(8)
}
pub fn enable_atomics(&self) -> bool {
self.numbered_predicate(9)
}
pub fn enable_safepoints(&self) -> bool {
self.numbered_predicate(10)
}
pub fn emit_all_ones_funcaddrs(&self) -> bool {
self.numbered_predicate(11)
}
pub fn enable_probestack(&self) -> bool {
self.numbered_predicate(12)
}
pub fn probestack_func_adjusts_sp(&self) -> bool {
self.numbered_predicate(13)
}
pub fn enable_jump_tables(&self) -> bool {
self.numbered_predicate(14)
}
}
static DESCRIPTORS: [detail::Descriptor; 19] = [
detail::Descriptor {
name: "opt_level",
offset: 0,
detail: detail::Detail::Enum { last: 2, enumerators: 0 },
},
detail::Descriptor {
name: "libcall_call_conv",
offset: 1,
detail: detail::Detail::Enum { last: 7, enumerators: 3 },
},
detail::Descriptor {
name: "baldrdash_prologue_words",
offset: 2,
detail: detail::Detail::Num,
},
detail::Descriptor {
name: "probestack_size_log2",
offset: 3,
detail: detail::Detail::Num,
},
detail::Descriptor {
name: "enable_verifier",
offset: 4,
detail: detail::Detail::Bool { bit: 0 },
},
detail::Descriptor {
name: "is_pic",
offset: 4,
detail: detail::Detail::Bool { bit: 1 },
},
detail::Descriptor {
name: "use_colocated_libcalls",
offset: 4,
detail: detail::Detail::Bool { bit: 2 },
},
detail::Descriptor {
name: "avoid_div_traps",
offset: 4,
detail: detail::Detail::Bool { bit: 3 },
},
detail::Descriptor {
name: "enable_float",
offset: 4,
detail: detail::Detail::Bool { bit: 4 },
},
detail::Descriptor {
name: "enable_nan_canonicalization",
offset: 4,
detail: detail::Detail::Bool { bit: 5 },
},
detail::Descriptor {
name: "enable_pinned_reg",
offset: 4,
detail: detail::Detail::Bool { bit: 6 },
},
detail::Descriptor {
name: "use_pinned_reg_as_heap_base",
offset: 4,
detail: detail::Detail::Bool { bit: 7 },
},
detail::Descriptor {
name: "enable_simd",
offset: 5,
detail: detail::Detail::Bool { bit: 0 },
},
detail::Descriptor {
name: "enable_atomics",
offset: 5,
detail: detail::Detail::Bool { bit: 1 },
},
detail::Descriptor {
name: "enable_safepoints",
offset: 5,
detail: detail::Detail::Bool { bit: 2 },
},
detail::Descriptor {
name: "emit_all_ones_funcaddrs",
offset: 5,
detail: detail::Detail::Bool { bit: 3 },
},
detail::Descriptor {
name: "enable_probestack",
offset: 5,
detail: detail::Detail::Bool { bit: 4 },
},
detail::Descriptor {
name: "probestack_func_adjusts_sp",
offset: 5,
detail: detail::Detail::Bool { bit: 5 },
},
detail::Descriptor {
name: "enable_jump_tables",
offset: 5,
detail: detail::Detail::Bool { bit: 6 },
},
];
static ENUMERATORS: [&str; 11] = [
"none",
"speed",
"speed_and_size",
"isa_default",
"fast",
"cold",
"system_v",
"windows_fastcall",
"baldrdash_system_v",
"baldrdash_windows",
"probestack",
];
static HASH_TABLE: [u16; 32] = [
0xffff,
16,
0xffff,
9,
0xffff,
4,
13,
11,
12,
17,
0xffff,
0xffff,
3,
0xffff,
14,
0xffff,
10,
0xffff,
0xffff,
7,
15,
6,
18,
1,
0xffff,
0xffff,
0xffff,
0xffff,
0,
2,
8,
5,
];
static PRESETS: [(u8, u8); 0] = [
];
static TEMPLATE: detail::Template = detail::Template {
name: "shared",
descriptors: &DESCRIPTORS,
enumerators: &ENUMERATORS,
hash_table: &HASH_TABLE,
defaults: &[0x00, 0x00, 0x00, 0x0c, 0x11, 0x52],
presets: &PRESETS,
};
pub fn builder() -> Builder {
Builder::new(&TEMPLATE)
}
impl fmt::Display for Flags {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
writeln!(f, "[shared]")?;
for d in &DESCRIPTORS {
if !d.detail.is_preset() {
write!(f, "{} = ", d.name)?;
TEMPLATE.format_toml_value(d.detail, self.bytes[d.offset as usize], f)?;
writeln!(f)?;
}
}
Ok(())
}
}