llvm-project/llvm/test/TableGen/generic-tables-return-range.td
Garvit Gupta 6c903f05f3
[TableGen] Add support for emitting new function definition to return a range of results for Primary Key (#96174)
In the RISC-V architecture, multiple vendor-specific Control and Status
Registers (CSRs) share the same encoding. However, the existing lookup
function, which currently returns only a single result, falls short.
During disassembly, it consistently returns the first CSR encountered,
which may not be the correct CSR for the subtarget.

To address this issue, we modify the function definition to return a
range of results. These results can then be iterated upon to identify
the CSR that best fits the subtarget’s feature requirements. The
behavior of this new definition is controlled by a variable named
`ReturnRange`, which defaults to `false`.

Specifically, this patch introduces support for emitting a new lookup
function for the primary key. This function returns a pair of iterators
pointing to the first and last values, providing a comprehensive range
of values that satisfy the query
2024-07-11 10:54:31 -07:00

66 lines
2.1 KiB
TableGen

// RUN: llvm-tblgen -gen-searchable-tables -I %p/../../include %s | FileCheck %s
include "llvm/TableGen/SearchableTable.td"
class SysReg<string name, bits<12> op> {
string Name = name;
bits<12> Encoding = op;
code FeaturesRequired = [{ {} }];
}
def List1 : GenericTable {
let FilterClass = "SysReg";
let Fields = [
"Name", "Encoding", "FeaturesRequired",
];
let PrimaryKey = [ "Encoding" ];
let PrimaryKeyName = "lookupSysRegByEncoding";
let PrimaryKeyReturnRange = true;
}
let FeaturesRequired = [{ {Feature1} }] in {
def : SysReg<"csr1", 0x7C0>;
}
let FeaturesRequired = [{ {Feature2} }] in {
def : SysReg<"csr2", 0x7C0>;
}
// CHECK: #ifdef GET_List1_DECL
// CHECK-NEXT: llvm::iterator_range<const SysReg *> lookupSysRegByEncoding(uint16_t Encoding);
// CHECK-NEXT: #endif
// CHECK: #ifdef GET_List1_IMPL
// CHECK-NEXT: constexpr SysReg List1[] = {
// CHECK-NEXT: { "csr1", 0x7C0, {Feature1} }, // 0
// CHECK-NEXT: { "csr2", 0x7C0, {Feature2} }, // 1
// CHECK-NEXT: };
// CHECK: llvm::iterator_range<const SysReg *> lookupSysRegByEncoding(uint16_t Encoding) {
// CHECK-NEXT: struct KeyType {
// CHECK-NEXT: uint16_t Encoding;
// CHECK-NEXT: };
// CHECK-NEXT: KeyType Key = {Encoding};
// CHECK-NEXT: struct Comp {
// CHECK-NEXT: bool operator()(const SysReg &LHS, const KeyType &RHS) const {
// CHECK-NEXT: if (LHS.Encoding < RHS.Encoding)
// CHECK-NEXT: return true;
// CHECK-NEXT: if (LHS.Encoding > RHS.Encoding)
// CHECK-NEXT: return false;
// CHECK-NEXT: return false;
// CHECK-NEXT: }
// CHECK-NEXT: bool operator()(const KeyType &LHS, const SysReg &RHS) const {
// CHECK-NEXT: if (LHS.Encoding < RHS.Encoding)
// CHECK-NEXT: return true;
// CHECK-NEXT: if (LHS.Encoding > RHS.Encoding)
// CHECK-NEXT: return false;
// CHECK-NEXT: return false;
// CHECK-NEXT: }
// CHECK-NEXT: };
// CHECK-NEXT: auto Table = ArrayRef(List1);
// CHECK-NEXT: auto It = std::equal_range(Table.begin(), Table.end(), Key, Comp());
// CHECK-NEXT: return llvm::make_range(It.first, It.second);
// CHECK-NEXT: }
// CHECK-NEXT: #endif