Move library crates under 'lib/'.
Give these crates each a more standard directory layout with sources in a 'src' sub-sirectory and Cargo.toml in the top lib/foo directory. Add license and description fields to each. The build script for the cretonne crate now lives in 'lib/cretonne/build.rs' separating it from the normal library sources under 'lib/cretonne/src'.
This commit is contained in:
14
lib/cretonne/src/isa/riscv/enc_tables.rs
Normal file
14
lib/cretonne/src/isa/riscv/enc_tables.rs
Normal file
@@ -0,0 +1,14 @@
|
||||
//! Encoding tables for RISC-V.
|
||||
|
||||
use ir::{Opcode, InstructionData};
|
||||
use ir::instructions::InstructionFormat;
|
||||
use ir::types;
|
||||
use predicates;
|
||||
use isa::enc_tables::{Level1Entry, Level2Entry};
|
||||
|
||||
// Include the generated encoding tables:
|
||||
// - `LEVEL1_RV32`
|
||||
// - `LEVEL1_RV64`
|
||||
// - `LEVEL2`
|
||||
// - `ENCLIST`
|
||||
include!(concat!(env!("OUT_DIR"), "/encoding-riscv.rs"));
|
||||
206
lib/cretonne/src/isa/riscv/mod.rs
Normal file
206
lib/cretonne/src/isa/riscv/mod.rs
Normal file
@@ -0,0 +1,206 @@
|
||||
//! RISC-V Instruction Set Architecture.
|
||||
|
||||
pub mod settings;
|
||||
mod enc_tables;
|
||||
|
||||
use super::super::settings as shared_settings;
|
||||
use isa::enc_tables::{self as shared_enc_tables, lookup_enclist, general_encoding};
|
||||
use isa::Builder as IsaBuilder;
|
||||
use isa::{TargetIsa, Encoding};
|
||||
use ir::{InstructionData, DataFlowGraph};
|
||||
|
||||
#[allow(dead_code)]
|
||||
struct Isa {
|
||||
shared_flags: shared_settings::Flags,
|
||||
isa_flags: settings::Flags,
|
||||
cpumode: &'static [shared_enc_tables::Level1Entry<u16>],
|
||||
}
|
||||
|
||||
pub fn isa_builder() -> IsaBuilder {
|
||||
IsaBuilder {
|
||||
setup: settings::builder(),
|
||||
constructor: isa_constructor,
|
||||
}
|
||||
}
|
||||
|
||||
fn isa_constructor(shared_flags: shared_settings::Flags,
|
||||
builder: &shared_settings::Builder)
|
||||
-> Box<TargetIsa> {
|
||||
let level1 = if shared_flags.is_64bit() {
|
||||
&enc_tables::LEVEL1_RV64[..]
|
||||
} else {
|
||||
&enc_tables::LEVEL1_RV32[..]
|
||||
};
|
||||
Box::new(Isa {
|
||||
isa_flags: settings::Flags::new(&shared_flags, builder),
|
||||
shared_flags: shared_flags,
|
||||
cpumode: level1,
|
||||
})
|
||||
}
|
||||
|
||||
impl TargetIsa for Isa {
|
||||
fn name(&self) -> &'static str {
|
||||
"riscv"
|
||||
}
|
||||
|
||||
fn flags(&self) -> &shared_settings::Flags {
|
||||
&self.shared_flags
|
||||
}
|
||||
|
||||
fn encode(&self, _: &DataFlowGraph, inst: &InstructionData) -> Option<Encoding> {
|
||||
lookup_enclist(inst.first_type(),
|
||||
inst.opcode(),
|
||||
self.cpumode,
|
||||
&enc_tables::LEVEL2[..])
|
||||
.and_then(|enclist_offset| {
|
||||
general_encoding(enclist_offset,
|
||||
&enc_tables::ENCLISTS[..],
|
||||
|instp| enc_tables::check_instp(inst, instp),
|
||||
|isap| self.isa_flags.numbered_predicate(isap as usize))
|
||||
})
|
||||
}
|
||||
|
||||
fn recipe_names(&self) -> &'static [&'static str] {
|
||||
&enc_tables::RECIPE_NAMES[..]
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use settings::{self, Configurable};
|
||||
use isa;
|
||||
use ir::{DataFlowGraph, InstructionData, Opcode};
|
||||
use ir::{types, immediates};
|
||||
|
||||
fn encstr(isa: &isa::TargetIsa, enc: isa::Encoding) -> String {
|
||||
isa.display_enc(enc).to_string()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_64bitenc() {
|
||||
let mut shared_builder = settings::builder();
|
||||
shared_builder.set_bool("is_64bit", true).unwrap();
|
||||
let shared_flags = settings::Flags::new(&shared_builder);
|
||||
let isa = isa::lookup("riscv").unwrap().finish(shared_flags);
|
||||
|
||||
let mut dfg = DataFlowGraph::new();
|
||||
let ebb = dfg.make_ebb();
|
||||
let arg64 = dfg.append_ebb_arg(ebb, types::I64);
|
||||
let arg32 = dfg.append_ebb_arg(ebb, types::I32);
|
||||
|
||||
// Try to encode iadd_imm.i64 vx1, -10.
|
||||
let inst64 = InstructionData::BinaryImm {
|
||||
opcode: Opcode::IaddImm,
|
||||
ty: types::I64,
|
||||
arg: arg64,
|
||||
imm: immediates::Imm64::new(-10),
|
||||
};
|
||||
|
||||
// ADDI is I/0b00100
|
||||
assert_eq!(encstr(&*isa, isa.encode(&dfg, &inst64).unwrap()), "I#04");
|
||||
|
||||
// Try to encode iadd_imm.i64 vx1, -10000.
|
||||
let inst64_large = InstructionData::BinaryImm {
|
||||
opcode: Opcode::IaddImm,
|
||||
ty: types::I64,
|
||||
arg: arg64,
|
||||
imm: immediates::Imm64::new(-10000),
|
||||
};
|
||||
|
||||
// Immediate is out of range for ADDI.
|
||||
assert_eq!(isa.encode(&dfg, &inst64_large), None);
|
||||
|
||||
// Create an iadd_imm.i32 which is encodable in RV64.
|
||||
let inst32 = InstructionData::BinaryImm {
|
||||
opcode: Opcode::IaddImm,
|
||||
ty: types::I32,
|
||||
arg: arg32,
|
||||
imm: immediates::Imm64::new(10),
|
||||
};
|
||||
|
||||
// ADDIW is I/0b00110
|
||||
assert_eq!(encstr(&*isa, isa.encode(&dfg, &inst32).unwrap()), "I#06");
|
||||
}
|
||||
|
||||
// Same as above, but for RV32.
|
||||
#[test]
|
||||
fn test_32bitenc() {
|
||||
let mut shared_builder = settings::builder();
|
||||
shared_builder.set_bool("is_64bit", false).unwrap();
|
||||
let shared_flags = settings::Flags::new(&shared_builder);
|
||||
let isa = isa::lookup("riscv").unwrap().finish(shared_flags);
|
||||
|
||||
let mut dfg = DataFlowGraph::new();
|
||||
let ebb = dfg.make_ebb();
|
||||
let arg64 = dfg.append_ebb_arg(ebb, types::I64);
|
||||
let arg32 = dfg.append_ebb_arg(ebb, types::I32);
|
||||
|
||||
// Try to encode iadd_imm.i64 vx1, -10.
|
||||
let inst64 = InstructionData::BinaryImm {
|
||||
opcode: Opcode::IaddImm,
|
||||
ty: types::I64,
|
||||
arg: arg64,
|
||||
imm: immediates::Imm64::new(-10),
|
||||
};
|
||||
|
||||
// ADDI is I/0b00100
|
||||
assert_eq!(isa.encode(&dfg, &inst64), None);
|
||||
|
||||
// Try to encode iadd_imm.i64 vx1, -10000.
|
||||
let inst64_large = InstructionData::BinaryImm {
|
||||
opcode: Opcode::IaddImm,
|
||||
ty: types::I64,
|
||||
arg: arg64,
|
||||
imm: immediates::Imm64::new(-10000),
|
||||
};
|
||||
|
||||
// Immediate is out of range for ADDI.
|
||||
assert_eq!(isa.encode(&dfg, &inst64_large), None);
|
||||
|
||||
// Create an iadd_imm.i32 which is encodable in RV32.
|
||||
let inst32 = InstructionData::BinaryImm {
|
||||
opcode: Opcode::IaddImm,
|
||||
ty: types::I32,
|
||||
arg: arg32,
|
||||
imm: immediates::Imm64::new(10),
|
||||
};
|
||||
|
||||
// ADDI is I/0b00100
|
||||
assert_eq!(encstr(&*isa, isa.encode(&dfg, &inst32).unwrap()), "I#04");
|
||||
|
||||
// Create an imul.i32 which is encodable in RV32, but only when use_m is true.
|
||||
let mul32 = InstructionData::Binary {
|
||||
opcode: Opcode::Imul,
|
||||
ty: types::I32,
|
||||
args: [arg32, arg32],
|
||||
};
|
||||
|
||||
assert_eq!(isa.encode(&dfg, &mul32), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rv32m() {
|
||||
let mut shared_builder = settings::builder();
|
||||
shared_builder.set_bool("is_64bit", false).unwrap();
|
||||
let shared_flags = settings::Flags::new(&shared_builder);
|
||||
|
||||
// Set the supports_m stting which in turn enables the use_m predicate that unlocks
|
||||
// encodings for imul.
|
||||
let mut isa_builder = isa::lookup("riscv").unwrap();
|
||||
isa_builder.set_bool("supports_m", true).unwrap();
|
||||
|
||||
let isa = isa_builder.finish(shared_flags);
|
||||
|
||||
let mut dfg = DataFlowGraph::new();
|
||||
let ebb = dfg.make_ebb();
|
||||
let arg32 = dfg.append_ebb_arg(ebb, types::I32);
|
||||
|
||||
// Create an imul.i32 which is encodable in RV32M.
|
||||
let mul32 = InstructionData::Binary {
|
||||
opcode: Opcode::Imul,
|
||||
ty: types::I32,
|
||||
args: [arg32, arg32],
|
||||
};
|
||||
assert_eq!(encstr(&*isa, isa.encode(&dfg, &mul32).unwrap()), "R#10c");
|
||||
}
|
||||
}
|
||||
49
lib/cretonne/src/isa/riscv/settings.rs
Normal file
49
lib/cretonne/src/isa/riscv/settings.rs
Normal file
@@ -0,0 +1,49 @@
|
||||
//! RISC-V Settings.
|
||||
|
||||
use settings::{self, detail, Builder};
|
||||
use std::fmt;
|
||||
|
||||
// Include code generated by `meta/gen_settings.py`. This file contains a public `Flags` struct
|
||||
// with an impl for all of the settings defined in `meta/cretonne/settings.py`.
|
||||
include!(concat!(env!("OUT_DIR"), "/settings-riscv.rs"));
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::{builder, Flags};
|
||||
use settings::{self, Configurable};
|
||||
|
||||
#[test]
|
||||
fn display_default() {
|
||||
let shared = settings::Flags::new(&settings::builder());
|
||||
let b = builder();
|
||||
let f = Flags::new(&shared, &b);
|
||||
assert_eq!(f.to_string(),
|
||||
"[riscv]\n\
|
||||
supports_m = false\n\
|
||||
supports_a = false\n\
|
||||
supports_f = false\n\
|
||||
supports_d = false\n\
|
||||
enable_m = true\n");
|
||||
// Predicates are not part of the Display output.
|
||||
assert_eq!(f.full_float(), false);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn predicates() {
|
||||
let shared = settings::Flags::new(&settings::builder());
|
||||
let mut b = builder();
|
||||
b.set_bool("supports_f", true).unwrap();
|
||||
b.set_bool("supports_d", true).unwrap();
|
||||
let f = Flags::new(&shared, &b);
|
||||
assert_eq!(f.full_float(), true);
|
||||
|
||||
let mut sb = settings::builder();
|
||||
sb.set_bool("enable_simd", false).unwrap();
|
||||
let shared = settings::Flags::new(&sb);
|
||||
let mut b = builder();
|
||||
b.set_bool("supports_f", true).unwrap();
|
||||
b.set_bool("supports_d", true).unwrap();
|
||||
let f = Flags::new(&shared, &b);
|
||||
assert_eq!(f.full_float(), false);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user