-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Use Dyninst for x86_64 classification of types (#34)
* Refactor getRegisterClassFromType to use Dyninst for type processing This also adds a first-pass at handling some cases for vectors of floating point types. * Fix comment * Add placeholders for classifying types other than scalars * Tidy up includes in allocators.hpp * Merge getRegisterString and getRegistersString This also expands vector register handling. * Use the new interfaces for classification and allocation. * Remove unused variables in parse_parameters * Use exact name matching in get_one Also, don't copy and edit the vector- just return the found function. * Generate test cases programmatically This will allow us to more easily expand test cases later when we add pointers, references, aggregate types, and multiple parameters per function. Also, change the test function linkages to C-style so that exact name matching can be done instead of the broken pattern matching that was done previously in `get_one`. * Rename `Class` to `classification` * Combine the x87 register allocation checks * Use dyninst master for build in main.yaml * Use dyninst master for style tests * Use dyninst master for docs tests Co-authored-by: Vanessasaurus <814322+vsoch@users.noreply.github.com>
- Loading branch information
Showing
9 changed files
with
714 additions
and
410 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
// Copyright 2013-2021 Lawrence Livermore National Security, LLC and other | ||
// Spack Project Developers. See the top-level COPYRIGHT file for details. | ||
// | ||
// SPDX-License-Identifier: (Apache-2.0 OR MIT) | ||
|
||
#pragma once | ||
|
||
#include <utility> | ||
|
||
#include "Type.h" | ||
#include "register_class.hpp" | ||
|
||
namespace smeagle::x86_64 { | ||
|
||
struct classification { | ||
RegisterClass lo, hi; | ||
int pointer_indirections; | ||
std::string name; | ||
}; | ||
|
||
namespace st = Dyninst::SymtabAPI; | ||
|
||
inline classification classify(st::typeScalar *t, int ptr_cnt) { | ||
// size in BITS | ||
const auto size = t->getSize() * 8; | ||
|
||
if (ptr_cnt > 0) { | ||
/* | ||
* A pointer to a type X is converted to three abi_typelocation rules: | ||
* 1) A Pointer64 type at the base location and the base direction. | ||
* | ||
* 2) A recursive conversion of application type X, at location “(base location)” | ||
* (the base location wrapped in parentheses) and with direction ‘Export’. | ||
* | ||
* 3) A recursive conversion of application type X, at location “(base location)” | ||
* (the base location wrapped in parentheses) and with direction ‘Import’. | ||
* | ||
* For example, an application type int* at base location %rax and direction ‘Import’ | ||
* would convert to: abi_typelocation(..., Import, Pointer64, “%rax”). abi_typelocation(..., | ||
* Export, Integer32, “(%rax)”). abi_typelocation(..., Import, Integer32, “(%rax)”). | ||
* | ||
*/ | ||
// TODO Should we integrate the directionality calculation here? | ||
return {RegisterClass::INTEGER, RegisterClass::NO_CLASS, ptr_cnt, "Pointer64"}; | ||
} | ||
|
||
// paramType properties have booleans to indicate types | ||
auto const &props = t->properties(); | ||
|
||
// Integral types | ||
if (props.is_integral || props.is_UTF) { | ||
if (size > 128) { | ||
return {RegisterClass::SSE, RegisterClass::SSEUP, ptr_cnt, | ||
"IntegerVec" + std::to_string(size)}; | ||
} | ||
if (size == 128) { | ||
// __int128 is treated as struct{long,long}; | ||
// This is NOT correct, but we don't handle aggregates yet. | ||
// How do we differentiate between __int128 and __m128i? | ||
return {RegisterClass::MEMORY, RegisterClass::NO_CLASS, ptr_cnt, "Integer128"}; | ||
} | ||
|
||
// _Decimal32, _Decimal64, and __m64 are supposed to be SSE. | ||
// TODO How can we differentiate them here? | ||
return {RegisterClass::INTEGER, RegisterClass::NO_CLASS, ptr_cnt, | ||
"Integer" + std::to_string(size)}; | ||
} | ||
|
||
if (props.is_floating_point) { | ||
if (props.is_complex_float) { | ||
if (size == 128) { | ||
// x87 `complex long double` | ||
return {RegisterClass::COMPLEX_X87, RegisterClass::NO_CLASS, ptr_cnt, "CplxFloat128"}; | ||
} | ||
// This is NOT correct. | ||
// TODO It should be struct{T r,i;};, but we don't handle aggregates yet | ||
std::cout << "CplxFloat: " << t->getName() << " [" << t->getSize() << "]" << std::endl; | ||
return {RegisterClass::MEMORY, RegisterClass::NO_CLASS, ptr_cnt, | ||
"CplxFloat" + std::to_string(size / 2)}; | ||
} | ||
if (size <= 64) { | ||
// 32- or 64-bit floats | ||
return {RegisterClass::SSE, RegisterClass::SSEUP, ptr_cnt, "Float" + std::to_string(size)}; | ||
} | ||
if (size == 128) { | ||
// x87 `long double` OR __m128[d] | ||
// TODO: How do we differntiate the vector type here? Dyninst should help us | ||
return {RegisterClass::X87, RegisterClass::X87UP, ptr_cnt, "Float128"}; | ||
} | ||
if (size > 128) { | ||
return {RegisterClass::SSE, RegisterClass::SSEUP, ptr_cnt, | ||
"FloatVec" + std::to_string(size)}; | ||
} | ||
} | ||
|
||
throw std::runtime_error{"Unknown scalar type"}; | ||
} | ||
|
||
inline classification classify(st::typeStruct *) { return {}; } | ||
inline classification classify(st::typeUnion *) { return {}; } | ||
inline classification classify(st::typeArray *) { return {}; } | ||
inline classification classify(st::typeEnum *) { return {}; } | ||
inline classification classify(st::typeFunction *) { return {}; } | ||
|
||
} // namespace smeagle::x86_64 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.