From c679a2e746b836a17ea9a383247ebcbfd3fcb6b7 Mon Sep 17 00:00:00 2001 From: Jakob Stoklund Olesen Date: Fri, 5 Aug 2016 09:55:53 -0700 Subject: [PATCH] Scaffold implementation of the TargetIsa trait. More to come here. --- cranelift/src/libcretonne/isa/mod.rs | 42 ++++++++++++++++++++++++++-- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/cranelift/src/libcretonne/isa/mod.rs b/cranelift/src/libcretonne/isa/mod.rs index e2f48e7bbe..cd9749e6ee 100644 --- a/cranelift/src/libcretonne/isa/mod.rs +++ b/cranelift/src/libcretonne/isa/mod.rs @@ -1,6 +1,44 @@ //! Instruction Set Architectures. //! -//! The sub-modules of this `isa` module provide definitions for the instruction sets that Cretonne -//! can target. +//! The `isa` module provides a `TargetIsa` trait which provides the behavior specialization needed +//! by the ISA-independent code generator. +//! +//! The sub-modules of this module provide definitions for the instruction sets that Cretonne +//! can target. Each sub-module has it's own implementation of `TargetIsa`. pub mod riscv; + +use ir::dfg::DataFlowGraph; +use ir::entities::Inst; + +pub trait TargetIsa { + /// Encode an instruction after determining it is legal. + /// + /// If `inst` can legally be encoded in this ISA, produce the corresponding `Encoding` object. + /// Otherwise, return `None`. + /// + /// This is also the main entry point for determining if an instruction is legal. + fn encode(&self, dfg: &DataFlowGraph, inst: &Inst) -> Option; +} + +/// Bits needed to encode an instruction as binary machine code. +/// +/// The encoding consists of two parts, both specific to the target ISA: An encoding *recipe*, and +/// encoding *bits*. The recipe determines the native instruction format and the mapping of +/// operands to encoded bits. The encoding bits provide additional information to the recipe, +/// typically parts of the opcode. +pub struct Encoding(u32); + +impl Encoding { + /// Create a new `Encoding` containing `(recipe, bits)`. The `num_bits` parameter is the + /// ISA-dependent size of `bits`. + pub fn new(recipe: u32, bits: u32, num_bits: u8) -> Encoding { + Encoding((recipe << num_bits) | bits) + } + + /// Split the encoding into two parts: `(recipe, bits)`. Only the target ISA knows how many + /// bits are in each part. + pub fn split(&self, num_bits: u8) -> (u32, u32) { + (self.0 >> num_bits, self.0 & ((1 << num_bits) - 1)) + } +}