Pass Encoding to compute_size() for runtime Encoding inspection. #1156

In some cases, compute_size() is used to choose between various different Encodings
before one has been assigned to an instruction. For x86, the REX.W bit is stored
in the Encoding. To share recipes between REX/non-REX, that bit must be inspected
by compute_size().
This commit is contained in:
Sean Stangl
2019-11-07 11:43:08 -07:00
committed by Andrew Brown
parent 143cb01489
commit a06f2c87c2
2 changed files with 20 additions and 8 deletions

View File

@@ -80,23 +80,29 @@ impl fmt::Display for DisplayEncoding {
} }
} }
type SizeCalculatorFn = fn(&RecipeSizing, Inst, &RegDiversions, &Function) -> u8; type SizeCalculatorFn = fn(&RecipeSizing, Encoding, Inst, &RegDiversions, &Function) -> u8;
/// Returns the base size of the Recipe, assuming it's fixed. This is the default for most /// Returns the base size of the Recipe, assuming it's fixed. This is the default for most
/// encodings; others can be variable and longer than this base size, depending on the registers /// encodings; others can be variable and longer than this base size, depending on the registers
/// they're using and use a different function, specific per platform. /// they're using and use a different function, specific per platform.
pub fn base_size(sizing: &RecipeSizing, _: Inst, _: &RegDiversions, _: &Function) -> u8 { pub fn base_size(
sizing: &RecipeSizing,
_: Encoding,
_: Inst,
_: &RegDiversions,
_: &Function,
) -> u8 {
sizing.base_size sizing.base_size
} }
/// Code size information for an encoding recipe. /// Code size information for an encoding recipe.
/// ///
/// All encoding recipes correspond to an exact instruction size. /// Encoding recipes may have runtime-determined instruction size.
pub struct RecipeSizing { pub struct RecipeSizing {
/// Size in bytes of instructions encoded with this recipe. /// Minimum size in bytes of instructions encoded with this recipe.
pub base_size: u8, pub base_size: u8,
/// Method computing the real instruction's size, given inputs and outputs. /// Method computing the instruction's real size, given inputs and outputs.
pub compute_size: SizeCalculatorFn, pub compute_size: SizeCalculatorFn,
/// Allowed branch range in this recipe, if any. /// Allowed branch range in this recipe, if any.
@@ -132,7 +138,7 @@ impl EncInfo {
} }
} }
/// Get the precise size in bytes of instructions encoded with `enc`. /// Get the size in bytes of `inst`, if it were encoded with `enc`.
/// ///
/// Returns 0 for illegal encodings. /// Returns 0 for illegal encodings.
pub fn byte_size( pub fn byte_size(
@@ -144,7 +150,7 @@ impl EncInfo {
) -> CodeOffset { ) -> CodeOffset {
self.sizing.get(enc.recipe()).map_or(0, |s| { self.sizing.get(enc.recipe()).map_or(0, |s| {
let compute_size = s.compute_size; let compute_size = s.compute_size;
CodeOffset::from(compute_size(&s, inst, divert, func)) CodeOffset::from(compute_size(&s, enc, inst, divert, func))
}) })
} }

View File

@@ -10,7 +10,7 @@ use crate::ir::{self, Function, Inst, InstBuilder};
use crate::isa::constraints::*; use crate::isa::constraints::*;
use crate::isa::enc_tables::*; use crate::isa::enc_tables::*;
use crate::isa::encoding::base_size; use crate::isa::encoding::base_size;
use crate::isa::encoding::RecipeSizing; use crate::isa::encoding::{Encoding, RecipeSizing};
use crate::isa::RegUnit; use crate::isa::RegUnit;
use crate::isa::{self, TargetIsa}; use crate::isa::{self, TargetIsa};
use crate::predicates; use crate::predicates;
@@ -46,6 +46,7 @@ fn additional_size_if(
fn size_plus_maybe_offset_for_in_reg_0( fn size_plus_maybe_offset_for_in_reg_0(
sizing: &RecipeSizing, sizing: &RecipeSizing,
_enc: Encoding,
inst: Inst, inst: Inst,
divert: &RegDiversions, divert: &RegDiversions,
func: &Function, func: &Function,
@@ -54,6 +55,7 @@ fn size_plus_maybe_offset_for_in_reg_0(
} }
fn size_plus_maybe_offset_for_in_reg_1( fn size_plus_maybe_offset_for_in_reg_1(
sizing: &RecipeSizing, sizing: &RecipeSizing,
_enc: Encoding,
inst: Inst, inst: Inst,
divert: &RegDiversions, divert: &RegDiversions,
func: &Function, func: &Function,
@@ -62,6 +64,7 @@ fn size_plus_maybe_offset_for_in_reg_1(
} }
fn size_plus_maybe_sib_for_in_reg_0( fn size_plus_maybe_sib_for_in_reg_0(
sizing: &RecipeSizing, sizing: &RecipeSizing,
_enc: Encoding,
inst: Inst, inst: Inst,
divert: &RegDiversions, divert: &RegDiversions,
func: &Function, func: &Function,
@@ -70,6 +73,7 @@ fn size_plus_maybe_sib_for_in_reg_0(
} }
fn size_plus_maybe_sib_for_in_reg_1( fn size_plus_maybe_sib_for_in_reg_1(
sizing: &RecipeSizing, sizing: &RecipeSizing,
_enc: Encoding,
inst: Inst, inst: Inst,
divert: &RegDiversions, divert: &RegDiversions,
func: &Function, func: &Function,
@@ -78,6 +82,7 @@ fn size_plus_maybe_sib_for_in_reg_1(
} }
fn size_plus_maybe_sib_or_offset_for_in_reg_0( fn size_plus_maybe_sib_or_offset_for_in_reg_0(
sizing: &RecipeSizing, sizing: &RecipeSizing,
_enc: Encoding,
inst: Inst, inst: Inst,
divert: &RegDiversions, divert: &RegDiversions,
func: &Function, func: &Function,
@@ -86,6 +91,7 @@ fn size_plus_maybe_sib_or_offset_for_in_reg_0(
} }
fn size_plus_maybe_sib_or_offset_for_in_reg_1( fn size_plus_maybe_sib_or_offset_for_in_reg_1(
sizing: &RecipeSizing, sizing: &RecipeSizing,
_enc: Encoding,
inst: Inst, inst: Inst,
divert: &RegDiversions, divert: &RegDiversions,
func: &Function, func: &Function,