Path: blob/main/cranelift/codegen/meta/src/isa/riscv64.rs
1693 views
use crate::cdsl::isa::TargetIsa;1use crate::cdsl::settings::{PredicateNode, SettingGroupBuilder};23macro_rules! define_zvl_ext {4(DEF: $settings:expr, $size:expr) => {{5let name = concat!("has_zvl", $size, "b");6let desc = concat!("has extension Zvl", $size, "b?");7let comment = concat!(8"Zvl",9$size,10"b: Vector register has a minimum of ",11$size,12" bits"13);14$settings.add_bool(&name, &desc, &comment, false)15}};16($settings:expr, $size:expr $(, $implies:expr)*) => {{17let has_feature = define_zvl_ext!(DEF: $settings, $size);1819let name = concat!("zvl", $size, "b");20let desc = concat!("Has a vector register size of at least ", $size, " bits");2122let preset = $settings.add_preset(&name, &desc, preset!(has_feature $( && $implies )*));23(has_feature, preset)24}};25}2627pub(crate) fn define() -> TargetIsa {28let mut setting = SettingGroupBuilder::new("riscv64");2930// We target a minimum of riscv64g. That means that we have the following extensions by default:31//32// * M (integer multiplication and division)33// * A (atomic instructions)34// * F (single-precision floating point)35// * D (double-precision floating point)36// * Zicsr (control and status register instructions)37// * Zifencei (instruction-fetch fence)3839let has_m = setting.add_bool(40"has_m",41"has extension M?",42"Integer multiplication and division",43true,44);45let has_a = setting.add_bool("has_a", "has extension A?", "Atomic instructions", true);46let has_f = setting.add_bool(47"has_f",48"has extension F?",49"Single-precision floating point",50true,51);52let has_d = setting.add_bool(53"has_d",54"has extension D?",55"Double-precision floating point",56true,57);5859let _has_zfa = setting.add_bool(60"has_zfa",61"has extension Zfa?",62"Zfa: Extension for Additional Floating-Point Instructions",63false,64);6566let _has_zfhmin = setting.add_bool(67"has_zfhmin",68"has extension Zfhmin?",69"Zfhmin: Minimal Half-Precision Floating-Point",70false,71);7273let _has_zfh = setting.add_bool(74"has_zfh",75"has extension Zfh?",76"Zfh: Half-Precision Floating-Point Instructions",77false,78);7980let _has_v = setting.add_bool(81"has_v",82"has extension V?",83"Vector instruction support",84false,85);8687let _has_zvfh = setting.add_bool(88"has_zvfh",89"has extension Zvfh?",90"Zvfh: Vector Extension for Half-Precision Floating-Point",91false,92);9394let has_zca = setting.add_bool(95"has_zca",96"has extension Zca?",97"Zca is the C extension without floating point loads",98false,99);100let has_zcd = setting.add_bool(101"has_zcd",102"has extension Zcd?",103"Zcd contains only the double precision floating point loads from the C extension",104false,105);106setting.add_preset(107"has_c",108"Support for compressed instructions",109preset!(has_zca && has_zcd),110);111112let _has_zcb = setting.add_bool(113"has_zcb",114"has extension Zcb?",115"Zcb: Extra compressed instructions",116false,117);118119let _has_zbkb = setting.add_bool(120"has_zbkb",121"has extension zbkb?",122"Zbkb: Bit-manipulation for Cryptography",123false,124);125let _has_zba = setting.add_bool(126"has_zba",127"has extension zba?",128"Zba: Address Generation",129false,130);131let _has_zbb = setting.add_bool(132"has_zbb",133"has extension zbb?",134"Zbb: Basic bit-manipulation",135false,136);137let _has_zbc = setting.add_bool(138"has_zbc",139"has extension zbc?",140"Zbc: Carry-less multiplication",141false,142);143let _has_zbs = setting.add_bool(144"has_zbs",145"has extension zbs?",146"Zbs: Single-bit instructions",147false,148);149let _has_zicond = setting.add_bool(150"has_zicond",151"has extension zicond?",152"ZiCond: Integer Conditional Operations",153false,154);155156let has_zicsr = setting.add_bool(157"has_zicsr",158"has extension zicsr?",159"Zicsr: Control and Status Register (CSR) Instructions",160true,161);162let has_zifencei = setting.add_bool(163"has_zifencei",164"has extension zifencei?",165"Zifencei: Instruction-Fetch Fence",166true,167);168169// Zvl*: Minimum Vector Length Standard Extensions170// These extension specify the minimum number of bits in a vector register.171// Since it is a minimum, Zvl64b implies Zvl32b, Zvl128b implies Zvl64b, etc.172// The V extension supports a maximum of 64K bits in a single register.173//174// See: https://github.com/riscv/riscv-v-spec/blob/master/v-spec.adoc#181-zvl-minimum-vector-length-standard-extensions175let (_, zvl32b) = define_zvl_ext!(setting, 32);176let (_, zvl64b) = define_zvl_ext!(setting, 64, zvl32b);177let (_, zvl128b) = define_zvl_ext!(setting, 128, zvl64b);178let (_, zvl256b) = define_zvl_ext!(setting, 256, zvl128b);179let (_, zvl512b) = define_zvl_ext!(setting, 512, zvl256b);180let (_, zvl1024b) = define_zvl_ext!(setting, 1024, zvl512b);181let (_, zvl2048b) = define_zvl_ext!(setting, 2048, zvl1024b);182let (_, zvl4096b) = define_zvl_ext!(setting, 4096, zvl2048b);183let (_, zvl8192b) = define_zvl_ext!(setting, 8192, zvl4096b);184let (_, zvl16384b) = define_zvl_ext!(setting, 16384, zvl8192b);185let (_, zvl32768b) = define_zvl_ext!(setting, 32768, zvl16384b);186let (_, _zvl65536b) = define_zvl_ext!(setting, 65536, zvl32768b);187188setting.add_predicate(189"has_g",190predicate!(has_m && has_a && has_f && has_d && has_zicsr && has_zifencei),191);192193TargetIsa::new("riscv64", setting.build())194}195196197