1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * Copyright © 2022 Imagination Technologies Ltd. 3bf215546Sopenharmony_ci * 4bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a copy 5bf215546Sopenharmony_ci * of this software and associated documentation files (the "Software"), to deal 6bf215546Sopenharmony_ci * in the Software without restriction, including without limitation the rights 7bf215546Sopenharmony_ci * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8bf215546Sopenharmony_ci * copies of the Software, and to permit persons to whom the Software is 9bf215546Sopenharmony_ci * furnished to do so, subject to the following conditions: 10bf215546Sopenharmony_ci * 11bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next 12bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the 13bf215546Sopenharmony_ci * Software. 14bf215546Sopenharmony_ci * 15bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18bf215546Sopenharmony_ci * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20bf215546Sopenharmony_ci * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21bf215546Sopenharmony_ci * SOFTWARE. 22bf215546Sopenharmony_ci */ 23bf215546Sopenharmony_ci 24bf215546Sopenharmony_ci#include <assert.h> 25bf215546Sopenharmony_ci#include <stdarg.h> 26bf215546Sopenharmony_ci#include <stdbool.h> 27bf215546Sopenharmony_ci#include <stddef.h> 28bf215546Sopenharmony_ci#include <stdint.h> 29bf215546Sopenharmony_ci 30bf215546Sopenharmony_ci#include "rogue_encoders.h" 31bf215546Sopenharmony_ci#include "rogue_util.h" 32bf215546Sopenharmony_ci#include "util/bitscan.h" 33bf215546Sopenharmony_ci 34bf215546Sopenharmony_ci/** 35bf215546Sopenharmony_ci * \brief Passes the input value through unchanged. 36bf215546Sopenharmony_ci * 37bf215546Sopenharmony_ci * \param[in] value Pointer to the destination value. 38bf215546Sopenharmony_ci * \param[in] inputs Number of inputs provided. 39bf215546Sopenharmony_ci * \param[in] ... Input value(s). 40bf215546Sopenharmony_ci * \return true if encoding was successful. 41bf215546Sopenharmony_ci */ 42bf215546Sopenharmony_cibool rogue_encoder_pass(uint64_t *value, size_t inputs, ...) 43bf215546Sopenharmony_ci{ 44bf215546Sopenharmony_ci va_list args; 45bf215546Sopenharmony_ci 46bf215546Sopenharmony_ci assert(inputs == 1); 47bf215546Sopenharmony_ci 48bf215546Sopenharmony_ci va_start(args, inputs); 49bf215546Sopenharmony_ci *value = va_arg(args, uint64_t); 50bf215546Sopenharmony_ci va_end(args); 51bf215546Sopenharmony_ci 52bf215546Sopenharmony_ci return true; 53bf215546Sopenharmony_ci} 54bf215546Sopenharmony_ci 55bf215546Sopenharmony_ci/** 56bf215546Sopenharmony_ci * \brief Encoder for DRC values. 57bf215546Sopenharmony_ci * 58bf215546Sopenharmony_ci * \sa #rogue_encoder_pass() 59bf215546Sopenharmony_ci * 60bf215546Sopenharmony_ci * \param[in] value Pointer to the destination value. 61bf215546Sopenharmony_ci * \param[in] inputs Number of inputs provided. 62bf215546Sopenharmony_ci * \param[in] ... Input value(s). 63bf215546Sopenharmony_ci * \return true if encoding was successful. 64bf215546Sopenharmony_ci */ 65bf215546Sopenharmony_cibool rogue_encoder_drc(uint64_t *value, size_t inputs, ...) 66bf215546Sopenharmony_ci __attribute__((alias("rogue_encoder_pass"))); 67bf215546Sopenharmony_ci 68bf215546Sopenharmony_ci/** 69bf215546Sopenharmony_ci * \brief Encoder for immediate values. 70bf215546Sopenharmony_ci * 71bf215546Sopenharmony_ci * \sa #rogue_encoder_pass() 72bf215546Sopenharmony_ci * 73bf215546Sopenharmony_ci * \param[in] value Pointer to the destination value. 74bf215546Sopenharmony_ci * \param[in] inputs Number of inputs provided. 75bf215546Sopenharmony_ci * \param[in] ... Input value(s). 76bf215546Sopenharmony_ci * \return true if encoding was successful. 77bf215546Sopenharmony_ci */ 78bf215546Sopenharmony_cibool rogue_encoder_imm(uint64_t *value, size_t inputs, ...) 79bf215546Sopenharmony_ci __attribute__((alias("rogue_encoder_pass"))); 80bf215546Sopenharmony_ci 81bf215546Sopenharmony_ci/** 82bf215546Sopenharmony_ci * \brief Encodes input ranges {1..15 -> 1-15} and {16 -> 0}. 83bf215546Sopenharmony_ci * 84bf215546Sopenharmony_ci * The input should be in the range 1-16; the function represents 1-15 normally 85bf215546Sopenharmony_ci * and represents 16 by 0. 86bf215546Sopenharmony_ci * 87bf215546Sopenharmony_ci * \param[in] value Pointer to the destination value. 88bf215546Sopenharmony_ci * \param[in] inputs Number of inputs provided. 89bf215546Sopenharmony_ci * \param[in] ... Input value(s). 90bf215546Sopenharmony_ci * \return true if encoding was successful. 91bf215546Sopenharmony_ci */ 92bf215546Sopenharmony_cibool rogue_encoder_ls_1_16(uint64_t *value, size_t inputs, ...) 93bf215546Sopenharmony_ci{ 94bf215546Sopenharmony_ci va_list args; 95bf215546Sopenharmony_ci uint64_t input; 96bf215546Sopenharmony_ci 97bf215546Sopenharmony_ci assert(inputs == 1); 98bf215546Sopenharmony_ci 99bf215546Sopenharmony_ci va_start(args, inputs); 100bf215546Sopenharmony_ci input = va_arg(args, uint64_t); 101bf215546Sopenharmony_ci va_end(args); 102bf215546Sopenharmony_ci 103bf215546Sopenharmony_ci /* Validate the input range. */ 104bf215546Sopenharmony_ci if (!input || input > 16) { 105bf215546Sopenharmony_ci *value = UINT64_MAX; 106bf215546Sopenharmony_ci return false; 107bf215546Sopenharmony_ci } 108bf215546Sopenharmony_ci 109bf215546Sopenharmony_ci *value = input % 16; 110bf215546Sopenharmony_ci 111bf215546Sopenharmony_ci return true; 112bf215546Sopenharmony_ci} 113bf215546Sopenharmony_ci 114bf215546Sopenharmony_ci/** 115bf215546Sopenharmony_ci * \brief Encodes registers according to the number of bits needed to specify 116bf215546Sopenharmony_ci * the bank number and register number. 117bf215546Sopenharmony_ci * 118bf215546Sopenharmony_ci * \param[in] value Pointer to the destination value. 119bf215546Sopenharmony_ci * \param[in] bank_bits The number of bits used to represent the register bank. 120bf215546Sopenharmony_ci * \param[in] bank the register bank 121bf215546Sopenharmony_ci * \param[in] num_bits The number of bits used to represent the register number. 122bf215546Sopenharmony_ci * \param[in] num The register number. 123bf215546Sopenharmony_ci * \return true if encoding was successful. 124bf215546Sopenharmony_ci */ 125bf215546Sopenharmony_cistatic bool rogue_encoder_reg(uint64_t *value, 126bf215546Sopenharmony_ci size_t bank_bits, 127bf215546Sopenharmony_ci size_t bank, 128bf215546Sopenharmony_ci size_t num_bits, 129bf215546Sopenharmony_ci size_t num) 130bf215546Sopenharmony_ci{ 131bf215546Sopenharmony_ci /* Verify "num" fits in "num_bits" and "bank" fits in "bank_bits". */ 132bf215546Sopenharmony_ci assert(util_last_bit64(num) <= num_bits); 133bf215546Sopenharmony_ci assert(util_last_bit64(bank) <= bank_bits); 134bf215546Sopenharmony_ci 135bf215546Sopenharmony_ci *value = num; 136bf215546Sopenharmony_ci *value |= (bank << num_bits); 137bf215546Sopenharmony_ci 138bf215546Sopenharmony_ci return true; 139bf215546Sopenharmony_ci} 140bf215546Sopenharmony_ci 141bf215546Sopenharmony_ci/** 142bf215546Sopenharmony_ci * \brief Macro to define the rogue_encoder_reg variants. 143bf215546Sopenharmony_ci */ 144bf215546Sopenharmony_ci#define ROGUE_ENCODER_REG_VARIANT(bank_bits, num_bits) \ 145bf215546Sopenharmony_ci bool rogue_encoder_reg_##bank_bits##_##num_bits(uint64_t *value, \ 146bf215546Sopenharmony_ci size_t inputs, \ 147bf215546Sopenharmony_ci ...) \ 148bf215546Sopenharmony_ci { \ 149bf215546Sopenharmony_ci va_list args; \ 150bf215546Sopenharmony_ci size_t bank; \ 151bf215546Sopenharmony_ci size_t num; \ 152bf215546Sopenharmony_ci assert(inputs == 2); \ 153bf215546Sopenharmony_ci va_start(args, inputs); \ 154bf215546Sopenharmony_ci bank = va_arg(args, size_t); \ 155bf215546Sopenharmony_ci num = va_arg(args, size_t); \ 156bf215546Sopenharmony_ci va_end(args); \ 157bf215546Sopenharmony_ci return rogue_encoder_reg(value, bank_bits, bank, num_bits, num); \ 158bf215546Sopenharmony_ci } 159bf215546Sopenharmony_ci 160bf215546Sopenharmony_ciROGUE_ENCODER_REG_VARIANT(2, 8) 161bf215546Sopenharmony_ciROGUE_ENCODER_REG_VARIANT(3, 8) 162bf215546Sopenharmony_ciROGUE_ENCODER_REG_VARIANT(3, 11) 163bf215546Sopenharmony_ci 164bf215546Sopenharmony_ci#undef ROGUE_ENCODER_REG_VARIANT 165