Implement support for the abs intrinsic.

Note only floating point cases make it through as intrinsics. Also make sure we honor the alignment requests of the read-only data sections. Abs uses a 16-byte aligned constant mask.

Closes #329.
This commit is contained in:
Andy Ayers 2015-03-19 15:52:04 -07:00
Родитель f3a0c73299
Коммит 9e82cdd1f0
3 изменённых файлов: 34 добавлений и 3 удалений

Просмотреть файл

@ -274,9 +274,7 @@ public:
// Used for testing, client can force verification.
bool verForceVerification(void) override { return false; };
bool abs(IRNode *Arg1, IRNode **RetVal) override {
throw NotYetImplementedException("abs");
};
bool abs(IRNode *Arg1, IRNode **RetVal) override;
IRNode *argList() override;
IRNode *instParam() override;

Просмотреть файл

@ -50,11 +50,22 @@ uint8_t *EEMemoryManager::allocateDataSection(uintptr_t Size,
// We don't expect to see RW data requests.
assert(IsReadOnly);
// Pad for alignment needs.
unsigned int Offset = ((uint64_t)ReadOnlyDataUnallocated) % Alignment;
if (Offset > 0) {
ReadOnlyDataUnallocated += Alignment - Offset;
}
assert((((uint64_t)ReadOnlyDataUnallocated) % Alignment) == 0);
// There are multiple read-only sections, so we need to keep
// track of the current allocation point in the read-only memory region.
uint8_t *Result = ReadOnlyDataUnallocated;
ReadOnlyDataUnallocated += Size;
// Make sure we are not allocating more than we expected to.
assert(ReadOnlyDataUnallocated <=
(ReadOnlyDataBlock + this->Context->ReadOnlyDataSize));
return Result;
}

Просмотреть файл

@ -4518,6 +4518,28 @@ bool GenIR::disableCastClassOptimization() {
return true;
}
/// Optionally generate inline code for the \p abs opcode
///
/// \param Argument input value for abs
/// \param Result [out] resulting absolute value, if we decided to expand
/// \returns true if Result represents the absolute value.
bool GenIR::abs(IRNode *Argument, IRNode **Result) {
Type *Ty = Argument->getType();
// Only the floating point cases of System.Math.Abs are implemented via
// 'internallcall'.
if (Ty->isFloatingPointTy()) {
Type *Types[] = {Ty};
Value *FAbs = Intrinsic::getDeclaration(JitContext->CurrentModule,
Intrinsic::fabs, Types);
Value *Abs = LLVMBuilder->CreateCall(FAbs, Argument);
*Result = (IRNode *)Abs;
return true;
}
return false;
}
#pragma endregion
#pragma region STACK MAINTENANCE