8282182: Document algorithm used to encode aarch64 logical immediate operands.

Reviewed-by: ngasson, aph
This commit is contained in:
Andrew Dinn 2022-05-27 10:09:53 +00:00
parent 37ecbb461c
commit 22e2067349

View File

@ -124,9 +124,22 @@ static inline uint32_t uimm(uint32_t val, int hi, int lo)
return pickbits32(val, hi, lo);
}
// SPEC bits(M*N) Replicate(bits(M) x, integer N);
// this is just an educated guess
// SPEC
//
// bits(M*N) Replicate(bits(M) B, integer N);
//
// given bit string B of width M (M > 0) and count N (N > 0)
// concatenate N copies of B to generate a bit string of width N * M
// (N * M <= 64)
//
// inputs
// bits : bit string to be replicated starting from bit 0
// nbits : width of the bit string string passed in bits
// count : number of copies of bit string to be concatenated
//
// result
// a bit string containing count copies of input bit string
//
uint64_t replicate(uint64_t bits, int nbits, int count)
{
assert(count > 0, "must be");
@ -148,11 +161,74 @@ uint64_t replicate(uint64_t bits, int nbits, int count)
return result;
}
// this function writes the supplied bimm reference and returns a
// boolean to indicate success (1) or fail (0) because an illegal
// encoding must be treated as an UNALLOC instruction
// construct a 64 bit immediate value for a logical immediate operation
//
// SPEC:
//
// {(0,_), (1, uint64)} = expandLogicalImmediate(immN, immr, imms)
//
// For valid combinations of immN, immr and imms, this function
// replicates a derived bit string, whose width is a power of 2, into
// a 64 bit result and returns 1.
//
// for invalid combinations it fails and returns 0
//
// - immN and imms together define
//
// 1) the size, 2^k, of the bit string to be replicated (0 < k <= 6)
//
// 2) the number of bits, p, to set in the string (0 < p < 2^k)
//
// - immr defines a right rotation on the bit string determined by
// immN and imms
//
// bit field construction:
//
// create a bit string of width 2^k
//
// set the bottom p bits to 1
//
// rotate the bit string right by immr bits
//
// replicate the 2^k bit string into 64 bits
//
// derivation of k and p and validity checks:
//
// when immN is 1 then k == 6 and immr/imms are masked to 6 bit
// integers
//
// when immN is 0 then k is the index of the first 0 bit in imms and
// immr/imms are masked to k-bit integers (i.e. any leading 1s and the
// first 0 in imms determine dead bits of imms/immr)
//
// if (pre-masking) immr >= 2^k then fail and return 0 (this is a
// uniqueness constraint that ensures each output bit string is only
// generated by one valid combination of immN, imms and immr).
//
// if k == 0 then fail and return 0. Note that this means that
// 2^k > 1 or equivalently 2^k - 1 > 0
//
// If imms == all 1s (modulo 2^k) then fail and return 0. Note that
// this means that 0 <= imms < 2^k - 1
//
// set p = imms + 1. Consequently, 0 < p < 2^k which is the condition
// that an all 0s or all 1s bit pattern is never generated.
//
// example output:
//
// 11001111_11001111_11001111_11001111_11001111_11001111_11001111_11001111
//
// which corresponds to the inputs
//
// immN = 0, imms = 110101, immr = 000010
//
// For these inputs k = 3, 2^k = 8, p = 6, rotation = 2
//
// implementation note:
//
// For historical reasons the implementation of this function is much
// more convoluted than is really necessary.
// construct a 32 bit immediate value for a logical immediate operation
int expandLogicalImmediate(uint32_t immN, uint32_t immr,
uint32_t imms, uint64_t &bimm)
{