dynasm\arch\riscv/
riscvdata.rs

1//! this file contains the datastructure specification for the RISC-V encoding data
2use bitflags::bitflags;
3use lazy_static::lazy_static;
4
5use std::collections::{HashMap, hash_map};
6use super::ast::RegId;
7
8use std::fmt;
9
10/// A template contains the information for the static parts of an instruction encoding, as well
11/// as its bitsize and length
12#[derive(Debug, Clone, Copy, PartialEq, Eq)]
13pub enum Template {
14    /// A 16-bit compressed instruction (Needed for the C extension)
15    Compressed(u16),
16    /// A single 32-bit instruction
17    Single(u32),
18    // Two 32-bit instructions. Used for load/store reg, offset
19    Double(u32, u32),
20    // / A long instruction sequence. Used to load big immediates.
21    Many(&'static [u32])
22}
23
24
25bitflags! {
26    /// Flags indicating what ISA targets an instruction is valid on
27    #[derive(Debug, Clone, Copy)]
28    pub struct ISAFlags: u8 {
29        const RV32 = 0x01;
30        const RV64 = 0x02;
31    }
32
33
34    /// Flags specifying what ISA extensions are required for an instruction
35    // debug.rs opmap generation relies on the Ex_ prefixes being fixed,
36    // so change that if editing this.
37    #[derive(Debug, Clone, Copy)]
38    pub struct ExtensionFlags: u64 {
39        /// A: atomics
40        const Ex_A = 0x0000_0000_0000_0001;
41        /// C: compressed
42        const Ex_C = 0x0000_0000_0000_0002;
43        /// D: double fp support
44        const Ex_D = 0x0000_0000_0000_0004;
45        /// F: single fp support
46        const Ex_F = 0x0000_0000_0000_0008;
47        /// I: integer base instruction set
48        const Ex_I = 0x0000_0000_0000_0010;
49        /// M: multiply/divide
50        const Ex_M = 0x0000_0000_0000_0020;
51        /// Q: quad fp support
52        const Ex_Q = 0x0000_0000_0000_0040;
53        /// Zabha: byte and halfword atomics
54        const Ex_Zabha = 0x0000_0000_0000_0080;
55        /// Zacas: atomic compare and swap
56        const Ex_Zacas = 0x0000_0000_0000_0100;
57        /// Zawrs: wait-on-reservation-set
58        const Ex_Zawrs = 0x0000_0000_0000_0200;
59        /// Zba: bit manipulation address generation
60        const Ex_Zba = 0x0000_0000_0000_0400;
61        /// Zbb: basic bit manipulation
62        const Ex_Zbb = 0x0000_0000_0000_0800;
63        /// Zbc: carry-less multiplication
64        const Ex_Zbc = 0x0000_0000_0000_1000;
65        /// Zbkb: bit manipulation for cryptography
66        const Ex_Zbkb = 0x0000_0000_0000_2000;
67        /// Zbkc: carry-less multiplication for cryptography
68        const Ex_Zbkc = 0x0000_0000_0000_4000;
69        /// Zbkx: crossbar permutations
70        const Ex_Zbkx = 0x0000_0000_0000_8000;
71        /// Zbs: single-bit instructions
72        const Ex_Zbs = 0x0000_0000_0001_0000;
73        /// Zcb: simple code-size saving instructions
74        const Ex_Zcb = 0x0000_0000_0002_0000;
75        /// Zcmop: compressed may-be-operations
76        const Ex_Zcmop = 0x0000_0000_0004_0000;
77        /// Zcmp: compressed instruction sequences
78        const Ex_Zcmp = 0x0000_0000_0008_0000;
79        /// Zcmt: compressed table jump instructions
80        const Ex_Zcmt = 0x0000_0000_0010_0000;
81        /// Zdinx: double floating point in X registers
82        const Ex_Zdinx = 0x0000_0000_0020_0000;
83        /// Zfa: additional floating point instructions
84        const Ex_Zfa = 0x0000_0000_0040_0000;
85        /// Zfbfmin: Scalar convert to/from BF16
86        const Ex_Zfbfmin = 0x0000_0000_0080_0000;
87        /// Zfh: half-width fp support
88        const Ex_Zfh = 0x0000_0000_0100_0000;
89        /// Zfhmin: half-width fp support, conversion only
90        const Ex_Zfhmin = 0x0000_0000_0200_0000;
91        /// Zfinx: floating point in X registers
92        const Ex_Zfinx = 0x0000_0000_0400_0000;
93        /// Zhinx: half floating point in X registers
94        const Ex_Zhinx = 0x0000_0000_0800_0000;
95        /// Zhinxmin: half floating point in X registers, conversion only
96        const Ex_Zhinxmin = 0x0000_0000_1000_0000;
97        /// Zicbo: cache block management operations
98        const Ex_Zicbom = 0x0000_0000_2000_0000;
99        /// Zicbo: cache block prefetch operations
100        const Ex_Zicbop = 0x0000_0000_4000_0000;
101        /// Zicbo: cache block zero operations
102        const Ex_Zicboz = 0x0000_0000_8000_0000;
103        /// Zicfilp: control flow integrity landing pad
104        const Ex_Zicfilp = 0x0000_0001_0000_0000;
105        /// Zicfiss: Shadow stack
106        const Ex_Zicfiss = 0x0000_0002_0000_0000;
107        /// Zicntr: base counters and timers
108        const Ex_Zicntr = 0x0000_0004_0000_0000;
109        /// Zicond: conditional operations
110        const Ex_Zicond = 0x0000_0008_0000_0000;
111        /// Zicsr: control and status registers
112        const Ex_Zicsr = 0x0000_0010_0000_0000;
113        /// Zifencei: instruction-fetch fence
114        const Ex_Zifencei = 0x0000_0020_0000_0000;
115        /// Zihintntl: non-temporal hints
116        const Ex_Zihintntl = 0x0000_0040_0000_0000;
117        /// Zihintpause: pause hint
118        const Ex_Zihintpause = 0x0000_0080_0000_0000;
119        /// Zimop: may-be-operations
120        const Ex_Zimop = 0x0000_0100_0000_0000;
121        /// Zk: scalar cryptography
122        const Ex_Zk = 0x0000_0200_0000_0000;
123        /// Zkn: NIST algorithm suite
124        const Ex_Zkn = 0x0000_0400_0000_0000;
125        /// Zknd: NIST suite: AES decyrption
126        const Ex_Zknd = 0x0000_0800_0000_0000;
127        /// Zkne: NIST suite: AES encryption
128        const Ex_Zkne = 0x0000_1000_0000_0000;
129        /// Zknh: NIST suite: Hash functions
130        const Ex_Zknh = 0x0000_2000_0000_0000;
131        /// Zks: ShangMi algorithm suite
132        const Ex_Zks = 0x0000_4000_0000_0000;
133        /// Zksed: ShangMi suite: SM4 block cipher
134        const Ex_Zksed = 0x0000_8000_0000_0000;
135        /// Zksh: ShangMi suite: SM3 hash functions
136        const Ex_Zksh = 0x0001_0000_0000_0000;
137    }
138}
139
140
141impl ISAFlags {
142    const fn make(bits: u8) -> ISAFlags {
143        ISAFlags::from_bits_truncate(bits)
144    }
145}
146
147
148impl ExtensionFlags {
149    const fn make(bits: u64) -> ExtensionFlags {
150        ExtensionFlags::from_bits_truncate(bits)
151    }
152}
153
154impl fmt::Display for ExtensionFlags {
155    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
156        let mut encountered_z = false;
157
158        // assemble extension sets. only use underscores between Z flags
159        for (flag, bits) in self.iter_names() {
160            let flag = &flag[3..];
161
162            if encountered_z {
163                write!(f, "_")?;
164            }
165
166            write!(f, "{}", flag)?;
167
168            if flag.starts_with("Z") {
169                encountered_z = true;
170            }
171        }
172        Ok(())
173    }
174}
175
176impl Default for ExtensionFlags {
177    fn default() -> ExtensionFlags {
178        ExtensionFlags::Ex_I
179    }
180}
181
182
183/// Matchers. These validate the types of arguments passed to an instruction.
184#[derive(Debug, Clone, Copy, PartialEq)]
185pub enum Matcher {
186    /// A normal register
187    X,
188
189    /// A floating point register
190    F,
191
192    /// A specific register
193    Reg(RegId),
194
195    /// A vector register
196    // V,
197
198    /// An indirect reference to a register
199    Ref,
200
201    /// An indirect reference with offset. expands args to X, Imm
202    RefOffset,
203
204    /// An indirect reference with offset, with the base always being SP
205    RefSp,
206
207    /// An pc-relative indirect reference. The register ought to contain an address
208    /// generated by AUIPC for the same label
209    RefLabel,
210
211    /// An immediate
212    Imm,
213
214    /// A jump offset
215    Offset,
216
217    /// a random ident
218    Ident,
219
220    /// a register list
221    Xlist,
222
223    /// a literal
224    Lit(Literal)
225}
226
227#[derive(Debug, Clone, Copy, PartialEq)]
228pub enum Literal {
229    RTZ
230}
231
232impl Literal {
233    pub fn as_str(&self) -> &'static str {
234        match self {
235            Literal::RTZ => "rtz"
236        }
237    }
238}
239
240
241/// Encoding commands. They specify how arguments should be checked / encoded.
242///
243/// Unless otherwise stated, the first argument indicates the bottom-most bit of the affected bitfield
244#[derive(Debug, Clone)]
245pub enum Command {
246    // Meta commands
247
248    /// Repeat the same argument again, as it needs to be encoded twice
249    Repeat,
250
251    /// go to the next argument, if not done implicitly
252    Next,
253
254    // register fields
255
256    /// A normal 5-bit register encoding. Argument specifies
257    R(u8),
258
259    /// A normal 5-bit register encoding, but the register must be even
260    Reven(u8),
261
262    /// A 5-bit register encoding that cannot be x0
263    Rno0(u8),
264
265    /// A 5-bit register encoding that cannot be x0 or x2
266    Rno02(u8),
267
268    /// A 3-bit encoding for "popular" registers (x8-x15
269    Rpop(u8),
270
271    /// A 3-bit encoding that allows specifying any of s0-s7 (x5-x7, x18-22), as used in cm.mva01s
272    Rpops(u8),
273
274    /// A 3-bit encoding that allows specifying any of s0-s7 (x5-x7, x18-22), as used in cm.mva01s
275    /// It also enforces that this is a different register from the previous one
276    Rpops2(u8),
277
278    /// A register list, as used in cm.pop. values 3-15 encode ra, s0-s11
279    Rlist(u8),
280
281    // weird fields
282
283    /// Rounding mode. 3-bit encoding indicating (RNE, RTZ, RDN, RUP, RMM, _, _, DYN). DYN default
284    RoundingMode(u8),
285
286    /// fence specification. 4-bit field encoding each of the letters iorw
287    /// (input, output, read, write) to bits 3-0
288    FenceSpec(u8),
289
290    /// 12-bit field encoding CSRs. Used to provide support for encoding actual names
291    Csr(u8),
292
293    /// weird floating point immediate instruction
294    FloatingPointImmediate(u8),
295
296    /// Technically an immediate, but the way we encode this depends on the amount of items
297    /// in the previous register list. The boolean indicates if the value should be negated.
298    SPImm(u8, bool),
299
300    // immediate handling, validation fields
301
302    /// validate that the current arg is an unsigned value that fits in .0 bits, and that the
303    /// lower .1 bits are 0
304    UImm(u8, u8),
305
306    /// validate that the current arg is a signed value that fits in .0 bits, and that the
307    /// lower .1 bits are 0
308    SImm(u8, u8),
309
310    /// Same as SImm, but handles 64-bit values. No scaling support
311    BigImm(u8),
312
313    /// validate that the current arg is an unsigned value that fits in .0 bits, and that the
314    /// lower .1 bits are 0. Also check that the immediate is not 0
315    UImmNo0(u8, u8),
316
317    /// validate that the current arg is a signed value that fits in .0 bits, and that the
318    /// lower .1 bits are 0. Also check that the immediate is not 0
319    SImmNo0(u8, u8),
320
321    /// validate that the current arg is an unsigned value that fits in .0 bits, and that the
322    /// lower .1 bits are 1
323    UImmOdd(u8, u8),
324
325    /// Validate that the given argument conforms to .0 >= arg >= .1 
326    UImmRange(u16, u16),
327
328    // immediate handling, encoding fields.
329
330    /// Encode a slice of bits from a value .0 = offset, .1 = amount of bits, .2 = offset in value
331    BitRange(u8, u8, u8),
332
333    /// Encode a slice of bits from a value .0 = offset, .1 = amount of bits, .2 = offset in value,
334    /// but add 1 << (.2 - 1) to value before encoding to round it
335    RBitRange(u8, u8, u8),
336
337    /// some kind of offset for a jump.
338    Offset(Relocation),
339}
340
341#[derive(Debug, Clone, Copy, PartialEq, Eq)]
342pub enum Relocation {
343    // beq, beqz, bge, bgeu, bgez, bgt, bgtu, bgtz, ble, bleu, blez, blt, bltu, bltz, bne, bnez
344    // 12 bits, 2-bit scaled
345    B = 0,
346    // j, jal
347    // 20 bits, 2-bit scaled
348    J = 1,
349    // c.beqz, c.bnez
350    // 9 bits, 2-bit scaled
351    BC = 2,
352    // c.j, c.jal
353    // 12 bits, 2-bit scaled
354    JC = 3,
355    // auipc
356    // 32 bits, 12-bit scaled
357    HI20 = 4,
358    // loads, addi.
359    // 12 bits, no scaling
360    LO12 = 5,
361    // stores
362    // 12 bits, no scaling
363    LO12S = 6,
364    // pc-relative addrgen/load pseudo instructions
365    // 32 bits, no scaling
366    SPLIT32 = 7,
367    // pc-relative store pseudo instructions
368    // 32 bits, no scaling
369    SPLIT32S = 8,
370    // 8-bit literal
371    LITERAL8 = 9,
372    // 16-bit literal
373    LITERAL16 = 10,
374    // 32-bit literal
375    LITERAL32 = 12,
376    // 64-bit literal
377    LITERAL64 = 16,
378}
379
380impl Relocation {
381    pub fn to_id(self) -> u8 {
382        self as u8
383    }
384
385    pub fn size(self) -> u8 {
386        match self {
387            Relocation::LITERAL8 => 1,
388            Relocation::BC
389            | Relocation::JC
390            | Relocation::LITERAL16 => 2,
391            Relocation::B
392            | Relocation::J
393            | Relocation::HI20
394            | Relocation::LO12
395            | Relocation::LO12S
396            | Relocation::LITERAL32 => 4,
397            Relocation::SPLIT32
398            | Relocation::SPLIT32S
399            | Relocation::LITERAL64 => 8
400        }
401    }
402}
403
404
405#[derive(Debug, Clone, Copy)]
406pub struct Opdata {
407    /// The base template for the encoding.
408    pub template: Template,
409    /// What ISA targets this op is valid for
410    pub isa_flags: ISAFlags,
411    /// What (combination) of extensions is required for this instruction
412    pub ext_flags: &'static [ExtensionFlags],
413    /// A set of matchers capable of matching the instruction encoding that this instruction represents.
414    pub matchers: &'static [Matcher],
415    /// A sequence of encoder commands that check the matched instruction on validity and whose output gets orred together with the original template at runtime.
416    pub commands: &'static [Command],
417}
418
419macro_rules! SingleOp {
420    ( $template:expr, $isa:expr, [ $( $matcher:expr ),* ], [ $( $command:expr ),* ], [ $( $extension:expr ),* ] ) => {
421        {
422            const MATCHERS: &'static [Matcher] = {
423                #[allow(unused_imports)]
424                use self::Matcher::*;
425                &[ $(
426                    $matcher
427                ),* ]
428            };
429            const COMMANDS: &'static [Command] = {
430                #[allow(unused_imports)]
431                use self::Command::*;
432                #[allow(unused_imports)]
433                use self::Relocation::*;
434                &[ $(
435                    $command
436                ),* ]
437            };
438            const EXTENSIONS: &'static [ExtensionFlags] = {
439                #[allow(unused_imports)]
440                &[ $(
441                    ExtensionFlags::make($extension)
442                ),* ]
443            };
444
445            use self::Template::*;
446            Opdata {
447                template: $template,
448                isa_flags: ISAFlags::make($isa),
449                ext_flags: EXTENSIONS,
450                matchers: MATCHERS,
451                commands: COMMANDS,
452            }
453        }
454    }
455}
456
457macro_rules! Ops {
458    ( $( $name:tt = [ $( $template:expr , $isa:expr , [ $( $matcher:expr ),* ] => [ $( $command:expr ),* ] , [ $( $extension:expr ),* ] ; )+ ] , )* ) => {
459        [ $(
460            (
461                $name,
462                &[ $(
463                    SingleOp!( $template, $isa, [ $( $matcher ),* ], [ $( $command ),* ], [ $( $extension ),* ] )
464                ),+ ] as &[_]
465            )
466        ),* ]
467    }
468}
469
470pub fn get_mnemonic_data(name: &str) -> Option<&'static [Opdata]> {
471    OPMAP.get(&name).cloned()
472}
473
474#[allow(dead_code)]
475pub fn mnemonics() -> hash_map::Keys<'static, &'static str, &'static [Opdata]> {
476    OPMAP.keys()
477}
478
479
480lazy_static!{
481    static ref OPMAP: HashMap<&'static str, &'static [Opdata]> = {
482        #![allow(non_upper_case_globals)]
483
484        // we need to reimport these as we can't use bitflags in const
485        const RV32: u8 = ISAFlags::RV32.bits();
486        const RV64: u8 = ISAFlags::RV64.bits();
487
488        // yes these too...
489        const Ex_A: u64 = ExtensionFlags::Ex_A.bits();
490        const Ex_C: u64 = ExtensionFlags::Ex_C.bits();
491        const Ex_D: u64 = ExtensionFlags::Ex_D.bits();
492        const Ex_F: u64 = ExtensionFlags::Ex_F.bits();
493        const Ex_I: u64 = ExtensionFlags::Ex_I.bits();
494        const Ex_M: u64 = ExtensionFlags::Ex_M.bits();
495        const Ex_Q: u64 = ExtensionFlags::Ex_Q.bits();
496        const Ex_Zabha: u64 = ExtensionFlags::Ex_Zabha.bits();
497        const Ex_Zacas: u64 = ExtensionFlags::Ex_Zacas.bits();
498        const Ex_Zawrs: u64 = ExtensionFlags::Ex_Zawrs.bits();
499        const Ex_Zba: u64 = ExtensionFlags::Ex_Zba.bits();
500        const Ex_Zbb: u64 = ExtensionFlags::Ex_Zbb.bits();
501        const Ex_Zbc: u64 = ExtensionFlags::Ex_Zbc.bits();
502        const Ex_Zbkb: u64 = ExtensionFlags::Ex_Zbkb.bits();
503        const Ex_Zbkc: u64 = ExtensionFlags::Ex_Zbkc.bits();
504        const Ex_Zbkx: u64 = ExtensionFlags::Ex_Zbkx.bits();
505        const Ex_Zbs: u64 = ExtensionFlags::Ex_Zbs.bits();
506        const Ex_Zcb: u64 = ExtensionFlags::Ex_Zcb.bits();
507        const Ex_Zcmop: u64 = ExtensionFlags::Ex_Zcmop.bits();
508        const Ex_Zcmp: u64 = ExtensionFlags::Ex_Zcmp.bits();
509        const Ex_Zcmt: u64 = ExtensionFlags::Ex_Zcmt.bits();
510        const Ex_Zdinx: u64 = ExtensionFlags::Ex_Zdinx.bits();
511        const Ex_Zfa: u64 = ExtensionFlags::Ex_Zfa.bits();
512        const Ex_Zfbfmin: u64 = ExtensionFlags::Ex_Zfbfmin.bits();
513        const Ex_Zfh: u64 = ExtensionFlags::Ex_Zfh.bits();
514        const Ex_Zfhmin: u64 = ExtensionFlags::Ex_Zfhmin.bits();
515        const Ex_Zfinx: u64 = ExtensionFlags::Ex_Zfinx.bits();
516        const Ex_Zhinx: u64 = ExtensionFlags::Ex_Zhinx.bits();
517        const Ex_Zhinxmin: u64 = ExtensionFlags::Ex_Zhinxmin.bits();
518        const Ex_Zicbom: u64 = ExtensionFlags::Ex_Zicbom.bits();
519        const Ex_Zicbop: u64 = ExtensionFlags::Ex_Zicbop.bits();
520        const Ex_Zicboz: u64 = ExtensionFlags::Ex_Zicboz.bits();
521        const Ex_Zicfilp: u64 = ExtensionFlags::Ex_Zicfilp.bits();
522        const Ex_Zicfiss: u64 = ExtensionFlags::Ex_Zicfiss.bits();
523        const Ex_Zicntr: u64 = ExtensionFlags::Ex_Zicntr.bits();
524        const Ex_Zicond: u64 = ExtensionFlags::Ex_Zicond.bits();
525        const Ex_Zicsr: u64 = ExtensionFlags::Ex_Zicsr.bits();
526        const Ex_Zifencei: u64 = ExtensionFlags::Ex_Zifencei.bits();
527        const Ex_Zihintntl: u64 = ExtensionFlags::Ex_Zihintntl.bits();
528        const Ex_Zihintpause: u64 = ExtensionFlags::Ex_Zihintpause.bits();
529        const Ex_Zimop: u64 = ExtensionFlags::Ex_Zimop.bits();
530        const Ex_Zk: u64 = ExtensionFlags::Ex_Zk.bits();
531        const Ex_Zkn: u64 = ExtensionFlags::Ex_Zkn.bits();
532        const Ex_Zknd: u64 = ExtensionFlags::Ex_Zknd.bits();
533        const Ex_Zkne: u64 = ExtensionFlags::Ex_Zkne.bits();
534        const Ex_Zknh: u64 = ExtensionFlags::Ex_Zknh.bits();
535        const Ex_Zks: u64 = ExtensionFlags::Ex_Zks.bits();
536        const Ex_Zksed: u64 = ExtensionFlags::Ex_Zksed.bits();
537        const Ex_Zksh: u64 = ExtensionFlags::Ex_Zksh.bits();
538
539
540        static MAP: &[(&str, &[Opdata])] = &include!("opmap.rs");
541        MAP.iter().cloned().collect()
542    };
543
544    pub static ref ROUNDMODE_MAP: HashMap<&'static str, u8> = {
545        let mut map = HashMap::new();
546
547        map.insert("rne", 0);
548        map.insert("rtz", 1);
549        map.insert("rdn", 2);
550        map.insert("rup", 3);
551        map.insert("rmm", 4);
552        map.insert("dyn", 7);
553
554        map
555    };
556
557    pub static ref FENCESPEC_MAP: HashMap<&'static str, u8> = {
558        let mut map = HashMap::new();
559
560        map.insert("w", 1);
561        map.insert("r", 2);
562        map.insert("rw", 3);
563        map.insert("o", 4);
564        map.insert("ow", 5);
565        map.insert("or", 6);
566        map.insert("orw", 7);
567        map.insert("i", 8);
568        map.insert("iw", 9);
569        map.insert("ir", 10);
570        map.insert("irw", 11);
571        map.insert("io", 12);
572        map.insert("iow", 13);
573        map.insert("ior", 14);
574        map.insert("iorw", 15);
575
576        map
577    };
578
579    pub static ref CSR_MAP: HashMap<&'static str, u16> = {
580        let mut map = HashMap::new();
581
582        map.insert("fflags", 0x001);
583        map.insert("frm", 0x002);
584        map.insert("fcsr", 0x003);
585        map.insert("vstart", 0x008);
586        map.insert("vxsat", 0x009);
587        map.insert("vxrm", 0x00A);
588        map.insert("vcsr", 0x00F);
589        map.insert("ssp", 0x011);
590        map.insert("seed", 0x015);
591        map.insert("jvt", 0x017);
592        map.insert("cycle", 0xC00);
593        map.insert("time", 0xC01);
594        map.insert("instret", 0xC02);
595        map.insert("hpmcounter3", 0xC03);
596        map.insert("hpmcounter4", 0xC04);
597        map.insert("hpmcounter5", 0xC05);
598        map.insert("hpmcounter6", 0xC06);
599        map.insert("hpmcounter7", 0xC07);
600        map.insert("hpmcounter8", 0xC08);
601        map.insert("hpmcounter9", 0xC09);
602        map.insert("hpmcounter10", 0xC0A);
603        map.insert("hpmcounter11", 0xC0B);
604        map.insert("hpmcounter12", 0xC0C);
605        map.insert("hpmcounter13", 0xC0D);
606        map.insert("hpmcounter14", 0xC0E);
607        map.insert("hpmcounter15", 0xC0F);
608        map.insert("hpmcounter16", 0xC10);
609        map.insert("hpmcounter17", 0xC11);
610        map.insert("hpmcounter18", 0xC12);
611        map.insert("hpmcounter19", 0xC13);
612        map.insert("hpmcounter20", 0xC14);
613        map.insert("hpmcounter21", 0xC15);
614        map.insert("hpmcounter22", 0xC16);
615        map.insert("hpmcounter23", 0xC17);
616        map.insert("hpmcounter24", 0xC18);
617        map.insert("hpmcounter25", 0xC19);
618        map.insert("hpmcounter26", 0xC1A);
619        map.insert("hpmcounter27", 0xC1B);
620        map.insert("hpmcounter28", 0xC1C);
621        map.insert("hpmcounter29", 0xC1D);
622        map.insert("hpmcounter30", 0xC1E);
623        map.insert("hpmcounter31", 0xC1F);
624        map.insert("vl", 0xC20);
625        map.insert("vtype", 0xC21);
626        map.insert("vlenb", 0xC22);
627        map.insert("sstatus", 0x100);
628        map.insert("sedeleg", 0x102);
629        map.insert("sideleg", 0x103);
630        map.insert("sie", 0x104);
631        map.insert("stvec", 0x105);
632        map.insert("scounteren", 0x106);
633        map.insert("senvcfg", 0x10A);
634        map.insert("sstateen0", 0x10C);
635        map.insert("sstateen1", 0x10D);
636        map.insert("sstateen2", 0x10E);
637        map.insert("sstateen3", 0x10F);
638        map.insert("scountinhibit", 0x120);
639        map.insert("sscratch", 0x140);
640        map.insert("sepc", 0x141);
641        map.insert("scause", 0x142);
642        map.insert("stval", 0x143);
643        map.insert("sip", 0x144);
644        map.insert("stimecmp", 0x14D);
645        map.insert("sctrctl", 0x14E);
646        map.insert("sctrstatus", 0x14F);
647        map.insert("siselect", 0x150);
648        map.insert("sireg", 0x151);
649        map.insert("sireg2", 0x152);
650        map.insert("sireg3", 0x153);
651        map.insert("sireg4", 0x155);
652        map.insert("sireg5", 0x156);
653        map.insert("sireg6", 0x157);
654        map.insert("stopei", 0x15C);
655        map.insert("sctrdepth", 0x15F);
656        map.insert("satp", 0x180);
657        map.insert("srmcfg", 0x181);
658        map.insert("scontext", 0x5A8);
659        map.insert("vsstatus", 0x200);
660        map.insert("vsie", 0x204);
661        map.insert("vstvec", 0x205);
662        map.insert("vsscratch", 0x240);
663        map.insert("vsepc", 0x241);
664        map.insert("vscause", 0x242);
665        map.insert("vstval", 0x243);
666        map.insert("vsip", 0x244);
667        map.insert("vstimecmp", 0x24D);
668        map.insert("vsctrctl", 0x24E);
669        map.insert("vsiselect", 0x250);
670        map.insert("vsireg", 0x251);
671        map.insert("vsireg2", 0x252);
672        map.insert("vsireg3", 0x253);
673        map.insert("vsireg4", 0x255);
674        map.insert("vsireg5", 0x256);
675        map.insert("vsireg6", 0x257);
676        map.insert("vstopei", 0x25C);
677        map.insert("vsatp", 0x280);
678        map.insert("hstatus", 0x600);
679        map.insert("hedeleg", 0x602);
680        map.insert("hideleg", 0x603);
681        map.insert("hie", 0x604);
682        map.insert("htimedelta", 0x605);
683        map.insert("hcounteren", 0x606);
684        map.insert("hgeie", 0x607);
685        map.insert("hvien", 0x608);
686        map.insert("hvictl", 0x609);
687        map.insert("henvcfg", 0x60A);
688        map.insert("hstateen0", 0x60C);
689        map.insert("hstateen1", 0x60D);
690        map.insert("hstateen2", 0x60E);
691        map.insert("hstateen3", 0x60F);
692        map.insert("htval", 0x643);
693        map.insert("hip", 0x644);
694        map.insert("hvip", 0x645);
695        map.insert("hviprio1", 0x646);
696        map.insert("hviprio2", 0x647);
697        map.insert("htinst", 0x64A);
698        map.insert("hgatp", 0x680);
699        map.insert("hcontext", 0x6A8);
700        map.insert("hgeip", 0xE12);
701        map.insert("vstopi", 0xEB0);
702        map.insert("scountovf", 0xDA0);
703        map.insert("stopi", 0xDB0);
704        map.insert("utvt", 0x007);
705        map.insert("unxti", 0x045);
706        map.insert("uintstatus", 0x046);
707        map.insert("uscratchcsw", 0x048);
708        map.insert("uscratchcswl", 0x049);
709        map.insert("stvt", 0x107);
710        map.insert("snxti", 0x145);
711        map.insert("sintstatus", 0x146);
712        map.insert("sscratchcsw", 0x148);
713        map.insert("sscratchcswl", 0x149);
714        map.insert("mtvt", 0x307);
715        map.insert("mnxti", 0x345);
716        map.insert("mintstatus", 0x346);
717        map.insert("mscratchcsw", 0x348);
718        map.insert("mscratchcswl", 0x349);
719        map.insert("mstatus", 0x300);
720        map.insert("misa", 0x301);
721        map.insert("medeleg", 0x302);
722        map.insert("mideleg", 0x303);
723        map.insert("mie", 0x304);
724        map.insert("mtvec", 0x305);
725        map.insert("mcounteren", 0x306);
726        map.insert("mvien", 0x308);
727        map.insert("mvip", 0x309);
728        map.insert("menvcfg", 0x30a);
729        map.insert("mstateen0", 0x30C);
730        map.insert("mstateen1", 0x30D);
731        map.insert("mstateen2", 0x30E);
732        map.insert("mstateen3", 0x30F);
733        map.insert("mcountinhibit", 0x320);
734        map.insert("mscratch", 0x340);
735        map.insert("mepc", 0x341);
736        map.insert("mcause", 0x342);
737        map.insert("mtval", 0x343);
738        map.insert("mip", 0x344);
739        map.insert("mtinst", 0x34a);
740        map.insert("mtval2", 0x34b);
741        map.insert("mctrctl", 0x34E);
742        map.insert("miselect", 0x350);
743        map.insert("mireg", 0x351);
744        map.insert("mireg2", 0x352);
745        map.insert("mireg3", 0x353);
746        map.insert("mireg4", 0x355);
747        map.insert("mireg5", 0x356);
748        map.insert("mireg6", 0x357);
749        map.insert("mtopei", 0x35c);
750        map.insert("pmpcfg0", 0x3a0);
751        map.insert("pmpcfg1", 0x3a1);
752        map.insert("pmpcfg2", 0x3a2);
753        map.insert("pmpcfg3", 0x3a3);
754        map.insert("pmpcfg4", 0x3a4);
755        map.insert("pmpcfg5", 0x3a5);
756        map.insert("pmpcfg6", 0x3a6);
757        map.insert("pmpcfg7", 0x3a7);
758        map.insert("pmpcfg8", 0x3a8);
759        map.insert("pmpcfg9", 0x3a9);
760        map.insert("pmpcfg10", 0x3aa);
761        map.insert("pmpcfg11", 0x3ab);
762        map.insert("pmpcfg12", 0x3ac);
763        map.insert("pmpcfg13", 0x3ad);
764        map.insert("pmpcfg14", 0x3ae);
765        map.insert("pmpcfg15", 0x3af);
766        map.insert("pmpaddr0", 0x3b0);
767        map.insert("pmpaddr1", 0x3b1);
768        map.insert("pmpaddr2", 0x3b2);
769        map.insert("pmpaddr3", 0x3b3);
770        map.insert("pmpaddr4", 0x3b4);
771        map.insert("pmpaddr5", 0x3b5);
772        map.insert("pmpaddr6", 0x3b6);
773        map.insert("pmpaddr7", 0x3b7);
774        map.insert("pmpaddr8", 0x3b8);
775        map.insert("pmpaddr9", 0x3b9);
776        map.insert("pmpaddr10", 0x3ba);
777        map.insert("pmpaddr11", 0x3bb);
778        map.insert("pmpaddr12", 0x3bc);
779        map.insert("pmpaddr13", 0x3bd);
780        map.insert("pmpaddr14", 0x3be);
781        map.insert("pmpaddr15", 0x3bf);
782        map.insert("pmpaddr16", 0x3c0);
783        map.insert("pmpaddr17", 0x3c1);
784        map.insert("pmpaddr18", 0x3c2);
785        map.insert("pmpaddr19", 0x3c3);
786        map.insert("pmpaddr20", 0x3c4);
787        map.insert("pmpaddr21", 0x3c5);
788        map.insert("pmpaddr22", 0x3c6);
789        map.insert("pmpaddr23", 0x3c7);
790        map.insert("pmpaddr24", 0x3c8);
791        map.insert("pmpaddr25", 0x3c9);
792        map.insert("pmpaddr26", 0x3ca);
793        map.insert("pmpaddr27", 0x3cb);
794        map.insert("pmpaddr28", 0x3cc);
795        map.insert("pmpaddr29", 0x3cd);
796        map.insert("pmpaddr30", 0x3ce);
797        map.insert("pmpaddr31", 0x3cf);
798        map.insert("pmpaddr32", 0x3d0);
799        map.insert("pmpaddr33", 0x3d1);
800        map.insert("pmpaddr34", 0x3d2);
801        map.insert("pmpaddr35", 0x3d3);
802        map.insert("pmpaddr36", 0x3d4);
803        map.insert("pmpaddr37", 0x3d5);
804        map.insert("pmpaddr38", 0x3d6);
805        map.insert("pmpaddr39", 0x3d7);
806        map.insert("pmpaddr40", 0x3d8);
807        map.insert("pmpaddr41", 0x3d9);
808        map.insert("pmpaddr42", 0x3da);
809        map.insert("pmpaddr43", 0x3db);
810        map.insert("pmpaddr44", 0x3dc);
811        map.insert("pmpaddr45", 0x3dd);
812        map.insert("pmpaddr46", 0x3de);
813        map.insert("pmpaddr47", 0x3df);
814        map.insert("pmpaddr48", 0x3e0);
815        map.insert("pmpaddr49", 0x3e1);
816        map.insert("pmpaddr50", 0x3e2);
817        map.insert("pmpaddr51", 0x3e3);
818        map.insert("pmpaddr52", 0x3e4);
819        map.insert("pmpaddr53", 0x3e5);
820        map.insert("pmpaddr54", 0x3e6);
821        map.insert("pmpaddr55", 0x3e7);
822        map.insert("pmpaddr56", 0x3e8);
823        map.insert("pmpaddr57", 0x3e9);
824        map.insert("pmpaddr58", 0x3ea);
825        map.insert("pmpaddr59", 0x3eb);
826        map.insert("pmpaddr60", 0x3ec);
827        map.insert("pmpaddr61", 0x3ed);
828        map.insert("pmpaddr62", 0x3ee);
829        map.insert("pmpaddr63", 0x3ef);
830        map.insert("mseccfg", 0x747);
831        map.insert("tselect", 0x7a0);
832        map.insert("tdata1", 0x7a1);
833        map.insert("tdata2", 0x7a2);
834        map.insert("tdata3", 0x7a3);
835        map.insert("tinfo", 0x7a4);
836        map.insert("tcontrol", 0x7a5);
837        map.insert("mcontext", 0x7a8);
838        map.insert("mscontext", 0x7aa);
839        map.insert("dcsr", 0x7b0);
840        map.insert("dpc", 0x7b1);
841        map.insert("dscratch0", 0x7b2);
842        map.insert("dscratch1", 0x7b3);
843        map.insert("mcycle", 0xB00);
844        map.insert("minstret", 0xB02);
845        map.insert("mhpmcounter3", 0xB03);
846        map.insert("mhpmcounter4", 0xB04);
847        map.insert("mhpmcounter5", 0xB05);
848        map.insert("mhpmcounter6", 0xB06);
849        map.insert("mhpmcounter7", 0xB07);
850        map.insert("mhpmcounter8", 0xB08);
851        map.insert("mhpmcounter9", 0xB09);
852        map.insert("mhpmcounter10", 0xB0A);
853        map.insert("mhpmcounter11", 0xB0B);
854        map.insert("mhpmcounter12", 0xB0C);
855        map.insert("mhpmcounter13", 0xB0D);
856        map.insert("mhpmcounter14", 0xB0E);
857        map.insert("mhpmcounter15", 0xB0F);
858        map.insert("mhpmcounter16", 0xB10);
859        map.insert("mhpmcounter17", 0xB11);
860        map.insert("mhpmcounter18", 0xB12);
861        map.insert("mhpmcounter19", 0xB13);
862        map.insert("mhpmcounter20", 0xB14);
863        map.insert("mhpmcounter21", 0xB15);
864        map.insert("mhpmcounter22", 0xB16);
865        map.insert("mhpmcounter23", 0xB17);
866        map.insert("mhpmcounter24", 0xB18);
867        map.insert("mhpmcounter25", 0xB19);
868        map.insert("mhpmcounter26", 0xB1A);
869        map.insert("mhpmcounter27", 0xB1B);
870        map.insert("mhpmcounter28", 0xB1C);
871        map.insert("mhpmcounter29", 0xB1D);
872        map.insert("mhpmcounter30", 0xB1E);
873        map.insert("mhpmcounter31", 0xB1F);
874        map.insert("mcyclecfg", 0x321);
875        map.insert("minstretcfg", 0x322);
876        map.insert("mhpmevent3", 0x323);
877        map.insert("mhpmevent4", 0x324);
878        map.insert("mhpmevent5", 0x325);
879        map.insert("mhpmevent6", 0x326);
880        map.insert("mhpmevent7", 0x327);
881        map.insert("mhpmevent8", 0x328);
882        map.insert("mhpmevent9", 0x329);
883        map.insert("mhpmevent10", 0x32A);
884        map.insert("mhpmevent11", 0x32B);
885        map.insert("mhpmevent12", 0x32C);
886        map.insert("mhpmevent13", 0x32D);
887        map.insert("mhpmevent14", 0x32E);
888        map.insert("mhpmevent15", 0x32F);
889        map.insert("mhpmevent16", 0x330);
890        map.insert("mhpmevent17", 0x331);
891        map.insert("mhpmevent18", 0x332);
892        map.insert("mhpmevent19", 0x333);
893        map.insert("mhpmevent20", 0x334);
894        map.insert("mhpmevent21", 0x335);
895        map.insert("mhpmevent22", 0x336);
896        map.insert("mhpmevent23", 0x337);
897        map.insert("mhpmevent24", 0x338);
898        map.insert("mhpmevent25", 0x339);
899        map.insert("mhpmevent26", 0x33A);
900        map.insert("mhpmevent27", 0x33B);
901        map.insert("mhpmevent28", 0x33C);
902        map.insert("mhpmevent29", 0x33D);
903        map.insert("mhpmevent30", 0x33E);
904        map.insert("mhpmevent31", 0x33F);
905        map.insert("mvendorid", 0xF11);
906        map.insert("marchid", 0xF12);
907        map.insert("mimpid", 0xF13);
908        map.insert("mhartid", 0xF14);
909        map.insert("mconfigptr", 0xF15);
910        map.insert("mtopi", 0xFB0);
911
912        // 32-bit only csr's
913        map.insert("sieh", 0x114);
914        map.insert("siph", 0x154);
915        map.insert("stimecmph", 0x15D);
916        map.insert("vsieh", 0x214);
917        map.insert("vsiph", 0x254);
918        map.insert("vstimecmph", 0x25D);
919        map.insert("hedelegh", 0x612);
920        map.insert("htimedeltah", 0x615);
921        map.insert("hidelegh", 0x613);
922        map.insert("hvienh", 0x618);
923        map.insert("henvcfgh", 0x61A);
924        map.insert("hviph", 0x655);
925        map.insert("hviprio1h", 0x656);
926        map.insert("hviprio2h", 0x657);
927        map.insert("hstateen0h", 0x61C);
928        map.insert("hstateen1h", 0x61D);
929        map.insert("hstateen2h", 0x61E);
930        map.insert("hstateen3h", 0x61F);
931        map.insert("cycleh", 0xC80);
932        map.insert("timeh", 0xC81);
933        map.insert("instreth", 0xC82);
934        map.insert("hpmcounter3h", 0xC83);
935        map.insert("hpmcounter4h", 0xC84);
936        map.insert("hpmcounter5h", 0xC85);
937        map.insert("hpmcounter6h", 0xC86);
938        map.insert("hpmcounter7h", 0xC87);
939        map.insert("hpmcounter8h", 0xC88);
940        map.insert("hpmcounter9h", 0xC89);
941        map.insert("hpmcounter10h", 0xC8A);
942        map.insert("hpmcounter11h", 0xC8B);
943        map.insert("hpmcounter12h", 0xC8C);
944        map.insert("hpmcounter13h", 0xC8D);
945        map.insert("hpmcounter14h", 0xC8E);
946        map.insert("hpmcounter15h", 0xC8F);
947        map.insert("hpmcounter16h", 0xC90);
948        map.insert("hpmcounter17h", 0xC91);
949        map.insert("hpmcounter18h", 0xC92);
950        map.insert("hpmcounter19h", 0xC93);
951        map.insert("hpmcounter20h", 0xC94);
952        map.insert("hpmcounter21h", 0xC95);
953        map.insert("hpmcounter22h", 0xC96);
954        map.insert("hpmcounter23h", 0xC97);
955        map.insert("hpmcounter24h", 0xC98);
956        map.insert("hpmcounter25h", 0xC99);
957        map.insert("hpmcounter26h", 0xC9A);
958        map.insert("hpmcounter27h", 0xC9B);
959        map.insert("hpmcounter28h", 0xC9C);
960        map.insert("hpmcounter29h", 0xC9D);
961        map.insert("hpmcounter30h", 0xC9E);
962        map.insert("hpmcounter31h", 0xC9F);
963        map.insert("mstatush", 0x310);
964        map.insert("midelegh", 0x313);
965        map.insert("mieh", 0x314);
966        map.insert("mvienh", 0x318);
967        map.insert("mviph", 0x319);
968        map.insert("menvcfgh", 0x31A);
969        map.insert("mstateen0h", 0x31C);
970        map.insert("mstateen1h", 0x31D);
971        map.insert("mstateen2h", 0x31E);
972        map.insert("mstateen3h", 0x31F);
973        map.insert("miph", 0x354);
974        map.insert("mcyclecfgh", 0x721);
975        map.insert("minstretcfgh", 0x722);
976        map.insert("mhpmevent3h", 0x723);
977        map.insert("mhpmevent4h", 0x724);
978        map.insert("mhpmevent5h", 0x725);
979        map.insert("mhpmevent6h", 0x726);
980        map.insert("mhpmevent7h", 0x727);
981        map.insert("mhpmevent8h", 0x728);
982        map.insert("mhpmevent9h", 0x729);
983        map.insert("mhpmevent10h", 0x72A);
984        map.insert("mhpmevent11h", 0x72B);
985        map.insert("mhpmevent12h", 0x72C);
986        map.insert("mhpmevent13h", 0x72D);
987        map.insert("mhpmevent14h", 0x72E);
988        map.insert("mhpmevent15h", 0x72F);
989        map.insert("mhpmevent16h", 0x730);
990        map.insert("mhpmevent17h", 0x731);
991        map.insert("mhpmevent18h", 0x732);
992        map.insert("mhpmevent19h", 0x733);
993        map.insert("mhpmevent20h", 0x734);
994        map.insert("mhpmevent21h", 0x735);
995        map.insert("mhpmevent22h", 0x736);
996        map.insert("mhpmevent23h", 0x737);
997        map.insert("mhpmevent24h", 0x738);
998        map.insert("mhpmevent25h", 0x739);
999        map.insert("mhpmevent26h", 0x73A);
1000        map.insert("mhpmevent27h", 0x73B);
1001        map.insert("mhpmevent28h", 0x73C);
1002        map.insert("mhpmevent29h", 0x73D);
1003        map.insert("mhpmevent30h", 0x73E);
1004        map.insert("mhpmevent31h", 0x73F);
1005        map.insert("mnscratch", 0x740);
1006        map.insert("mnepc", 0x741);
1007        map.insert("mncause", 0x742);
1008        map.insert("mnstatus", 0x744);
1009        map.insert("mseccfgh", 0x757);
1010        map.insert("mcycleh", 0xB80);
1011        map.insert("minstreth", 0xB82);
1012        map.insert("mhpmcounter3h", 0xB83);
1013        map.insert("mhpmcounter4h", 0xB84);
1014        map.insert("mhpmcounter5h", 0xB85);
1015        map.insert("mhpmcounter6h", 0xB86);
1016        map.insert("mhpmcounter7h", 0xB87);
1017        map.insert("mhpmcounter8h", 0xB88);
1018        map.insert("mhpmcounter9h", 0xB89);
1019        map.insert("mhpmcounter10h", 0xB8A);
1020        map.insert("mhpmcounter11h", 0xB8B);
1021        map.insert("mhpmcounter12h", 0xB8C);
1022        map.insert("mhpmcounter13h", 0xB8D);
1023        map.insert("mhpmcounter14h", 0xB8E);
1024        map.insert("mhpmcounter15h", 0xB8F);
1025        map.insert("mhpmcounter16h", 0xB90);
1026        map.insert("mhpmcounter17h", 0xB91);
1027        map.insert("mhpmcounter18h", 0xB92);
1028        map.insert("mhpmcounter19h", 0xB93);
1029        map.insert("mhpmcounter20h", 0xB94);
1030        map.insert("mhpmcounter21h", 0xB95);
1031        map.insert("mhpmcounter22h", 0xB96);
1032        map.insert("mhpmcounter23h", 0xB97);
1033        map.insert("mhpmcounter24h", 0xB98);
1034        map.insert("mhpmcounter25h", 0xB99);
1035        map.insert("mhpmcounter26h", 0xB9A);
1036        map.insert("mhpmcounter27h", 0xB9B);
1037        map.insert("mhpmcounter28h", 0xB9C);
1038        map.insert("mhpmcounter29h", 0xB9D);
1039        map.insert("mhpmcounter30h", 0xB9E);
1040        map.insert("mhpmcounter31h", 0xB9F);
1041
1042        map
1043    };
1044
1045
1046
1047
1048    pub static ref FP_IMM_IDENT_MAP: HashMap<&'static str, u8> = {
1049        let mut map = HashMap::new();
1050
1051        map.insert("min", 1);
1052        map.insert("inf", 30);
1053        map.insert("nan", 31);
1054
1055        map
1056    };
1057
1058    pub static ref FP_IMM_VALUE_MAP: &'static [(f32, u8)] = &[
1059        (-1.0, 0),
1060        (1.52587890625e-05, 2),
1061        (3.0517578125e-05, 3),
1062        (3.90625e-03, 4),
1063        (7.8125e-03, 5),
1064        (0.0625, 6),
1065        (0.125, 7),
1066        (0.25, 8),
1067        (0.3125, 9),
1068        (0.375, 10),
1069        (0.4375, 11),
1070        (0.5, 12),
1071        (0.625, 13),
1072        (0.75, 14),
1073        (0.875, 15),
1074        (1.0, 16),
1075        (1.25, 17),
1076        (1.5, 18),
1077        (1.75, 19),
1078        (2.0, 20),
1079        (2.5, 21),
1080        (3.0, 22),
1081        (4.0, 23),
1082        (8.0, 24),
1083        (16.0, 25),
1084        (128.0, 26),
1085        (256.0, 27),
1086        (32768.0, 28),
1087        (65536.0, 29),
1088    ];
1089}