brintos

brintos / llvm-project-archived public Read only

0
0
Text · 14.2 KiB · f9efee6 Raw
296 lines · cpp
1//===-- SIModeRegisterDefaults.cpp ------------------------------*- C++ -*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "SIModeRegisterDefaults.h"10#include "GCNSubtarget.h"11 12using namespace llvm;13 14SIModeRegisterDefaults::SIModeRegisterDefaults(const Function &F,15                                               const GCNSubtarget &ST) {16  *this = getDefaultForCallingConv(F.getCallingConv());17 18  if (ST.hasIEEEMode()) {19    StringRef IEEEAttr = F.getFnAttribute("amdgpu-ieee").getValueAsString();20    if (!IEEEAttr.empty())21      IEEE = IEEEAttr == "true";22  }23 24  if (ST.hasDX10ClampMode()) {25    StringRef DX10ClampAttr =26        F.getFnAttribute("amdgpu-dx10-clamp").getValueAsString();27    if (!DX10ClampAttr.empty())28      DX10Clamp = DX10ClampAttr == "true";29  }30 31  StringRef DenormF32Attr =32      F.getFnAttribute("denormal-fp-math-f32").getValueAsString();33  if (!DenormF32Attr.empty())34    FP32Denormals = parseDenormalFPAttribute(DenormF32Attr);35 36  StringRef DenormAttr =37      F.getFnAttribute("denormal-fp-math").getValueAsString();38  if (!DenormAttr.empty()) {39    DenormalMode DenormMode = parseDenormalFPAttribute(DenormAttr);40    if (DenormF32Attr.empty())41      FP32Denormals = DenormMode;42    FP64FP16Denormals = DenormMode;43  }44}45 46using namespace AMDGPU;47 48/// Combine f32 and f64 rounding modes into a combined rounding mode value.49static constexpr uint32_t getModeRegisterRoundMode(uint32_t HWFP32Val,50                                                   uint32_t HWFP64Val) {51  return HWFP32Val << F32FltRoundOffset | HWFP64Val << F64FltRoundOffset;52}53 54static constexpr uint64_t encodeFltRoundsTable(uint32_t FltRoundsVal,55                                               uint32_t HWF32Val,56                                               uint32_t HWF64Val) {57  uint32_t ModeVal = getModeRegisterRoundMode(HWF32Val, HWF64Val);58  if (FltRoundsVal > TowardNegative)59    FltRoundsVal -= ExtendedFltRoundOffset;60 61  uint32_t BitIndex = ModeVal << 2;62  return static_cast<uint64_t>(FltRoundsVal) << BitIndex;63}64 65// Encode FLT_ROUNDS value where the two rounding modes are the same and use a66// standard value67static constexpr uint64_t68encodeFltRoundsTableSame(AMDGPUFltRounds FltRoundsMode, uint32_t HWVal) {69  return encodeFltRoundsTable(FltRoundsMode, HWVal, HWVal);70}71 72// Convert mode register encoded rounding mode to AMDGPUFltRounds73static constexpr AMDGPUFltRounds74decodeIndexFltRoundConversionTable(uint32_t HWMode) {75  uint32_t TableRead = (FltRoundConversionTable >> (HWMode << 2)) & 0xf;76  if (TableRead > TowardNegative)77    TableRead += ExtendedFltRoundOffset;78  return static_cast<AMDGPUFltRounds>(TableRead);79}80 81static constexpr uint32_t HWTowardZero = FP_ROUND_ROUND_TO_ZERO;82static constexpr uint32_t HWNearestTiesToEven = FP_ROUND_ROUND_TO_NEAREST;83static constexpr uint32_t HWTowardPositive = FP_ROUND_ROUND_TO_INF;84static constexpr uint32_t HWTowardNegative = FP_ROUND_ROUND_TO_NEGINF;85 86const uint64_t AMDGPU::FltRoundConversionTable =87    encodeFltRoundsTableSame(TowardZeroF32_TowardZeroF64, HWTowardZero) |88    encodeFltRoundsTableSame(NearestTiesToEvenF32_NearestTiesToEvenF64,89                             HWNearestTiesToEven) |90    encodeFltRoundsTableSame(TowardPositiveF32_TowardPositiveF64,91                             HWTowardPositive) |92    encodeFltRoundsTableSame(TowardNegativeF32_TowardNegativeF64,93                             HWTowardNegative) |94 95    encodeFltRoundsTable(TowardZeroF32_NearestTiesToEvenF64, HWTowardZero,96                         HWNearestTiesToEven) |97    encodeFltRoundsTable(TowardZeroF32_TowardPositiveF64, HWTowardZero,98                         HWTowardPositive) |99    encodeFltRoundsTable(TowardZeroF32_TowardNegativeF64, HWTowardZero,100                         HWTowardNegative) |101 102    encodeFltRoundsTable(NearestTiesToEvenF32_TowardZeroF64,103                         HWNearestTiesToEven, HWTowardZero) |104    encodeFltRoundsTable(NearestTiesToEvenF32_TowardPositiveF64,105                         HWNearestTiesToEven, HWTowardPositive) |106    encodeFltRoundsTable(NearestTiesToEvenF32_TowardNegativeF64,107                         HWNearestTiesToEven, HWTowardNegative) |108 109    encodeFltRoundsTable(TowardPositiveF32_TowardZeroF64, HWTowardPositive,110                         HWTowardZero) |111    encodeFltRoundsTable(TowardPositiveF32_NearestTiesToEvenF64,112                         HWTowardPositive, HWNearestTiesToEven) |113    encodeFltRoundsTable(TowardPositiveF32_TowardNegativeF64, HWTowardPositive,114                         HWTowardNegative) |115 116    encodeFltRoundsTable(TowardNegativeF32_TowardZeroF64, HWTowardNegative,117                         HWTowardZero) |118    encodeFltRoundsTable(TowardNegativeF32_NearestTiesToEvenF64,119                         HWTowardNegative, HWNearestTiesToEven) |120    encodeFltRoundsTable(TowardNegativeF32_TowardPositiveF64, HWTowardNegative,121                         HWTowardPositive);122 123// Verify evaluation of FltRoundConversionTable124 125// If both modes are the same, should return the standard values.126static_assert(decodeIndexFltRoundConversionTable(getModeRegisterRoundMode(127                  HWTowardZero, HWTowardZero)) == AMDGPUFltRounds::TowardZero);128static_assert(decodeIndexFltRoundConversionTable(getModeRegisterRoundMode(129                  HWNearestTiesToEven, HWNearestTiesToEven)) ==130              AMDGPUFltRounds::NearestTiesToEven);131static_assert(decodeIndexFltRoundConversionTable(getModeRegisterRoundMode(132                  HWTowardPositive, HWTowardPositive)) ==133              AMDGPUFltRounds::TowardPositive);134static_assert(decodeIndexFltRoundConversionTable(getModeRegisterRoundMode(135                  HWTowardNegative, HWTowardNegative)) ==136              AMDGPUFltRounds::TowardNegative);137 138static_assert(decodeIndexFltRoundConversionTable(getModeRegisterRoundMode(139                  HWTowardZero, HWNearestTiesToEven)) ==140              TowardZeroF32_NearestTiesToEvenF64);141static_assert(decodeIndexFltRoundConversionTable(142                  getModeRegisterRoundMode(HWTowardZero, HWTowardPositive)) ==143              TowardZeroF32_TowardPositiveF64);144static_assert(decodeIndexFltRoundConversionTable(145                  getModeRegisterRoundMode(HWTowardZero, HWTowardNegative)) ==146              TowardZeroF32_TowardNegativeF64);147 148static_assert(decodeIndexFltRoundConversionTable(getModeRegisterRoundMode(149                  HWNearestTiesToEven, HWTowardZero)) ==150              NearestTiesToEvenF32_TowardZeroF64);151static_assert(decodeIndexFltRoundConversionTable(getModeRegisterRoundMode(152                  HWNearestTiesToEven, HWTowardPositive)) ==153              NearestTiesToEvenF32_TowardPositiveF64);154static_assert(decodeIndexFltRoundConversionTable(getModeRegisterRoundMode(155                  HWNearestTiesToEven, HWTowardNegative)) ==156              NearestTiesToEvenF32_TowardNegativeF64);157 158static_assert(decodeIndexFltRoundConversionTable(159                  getModeRegisterRoundMode(HWTowardPositive, HWTowardZero)) ==160              TowardPositiveF32_TowardZeroF64);161static_assert(decodeIndexFltRoundConversionTable(getModeRegisterRoundMode(162                  HWTowardPositive, HWNearestTiesToEven)) ==163              TowardPositiveF32_NearestTiesToEvenF64);164static_assert(decodeIndexFltRoundConversionTable(getModeRegisterRoundMode(165                  HWTowardPositive, HWTowardNegative)) ==166              TowardPositiveF32_TowardNegativeF64);167 168static_assert(decodeIndexFltRoundConversionTable(169                  getModeRegisterRoundMode(HWTowardNegative, HWTowardZero)) ==170              TowardNegativeF32_TowardZeroF64);171static_assert(decodeIndexFltRoundConversionTable(getModeRegisterRoundMode(172                  HWTowardNegative, HWNearestTiesToEven)) ==173              TowardNegativeF32_NearestTiesToEvenF64);174static_assert(decodeIndexFltRoundConversionTable(getModeRegisterRoundMode(175                  HWTowardNegative, HWTowardPositive)) ==176              TowardNegativeF32_TowardPositiveF64);177 178// Decode FLT_ROUNDS into the hardware value where the two rounding modes are179// the same and use a standard value180static constexpr uint64_t encodeFltRoundsToHWTableSame(uint32_t HWVal,181                                                       uint32_t FltRoundsVal) {182  if (FltRoundsVal > TowardNegative)183    FltRoundsVal -= ExtendedFltRoundOffset;184 185  return static_cast<uint64_t>(getModeRegisterRoundMode(HWVal, HWVal))186         << (FltRoundsVal << 2);187}188 189/// Decode FLT_ROUNDS into the hardware value where the two rounding modes190/// different and use an extended value.191static constexpr uint64_t encodeFltRoundsToHWTable(uint32_t HWF32Val,192                                                   uint32_t HWF64Val,193                                                   uint32_t FltRoundsVal) {194  if (FltRoundsVal > TowardNegative)195    FltRoundsVal -= ExtendedFltRoundOffset;196  return static_cast<uint64_t>(getModeRegisterRoundMode(HWF32Val, HWF64Val))197         << (FltRoundsVal << 2);198}199 200const uint64_t AMDGPU::FltRoundToHWConversionTable =201    encodeFltRoundsToHWTableSame(HWTowardZero, TowardZeroF32_TowardZeroF64) |202    encodeFltRoundsToHWTableSame(HWNearestTiesToEven,203                                 NearestTiesToEvenF32_NearestTiesToEvenF64) |204    encodeFltRoundsToHWTableSame(HWTowardPositive,205                                 TowardPositiveF32_TowardPositiveF64) |206    encodeFltRoundsToHWTableSame(HWTowardNegative,207                                 TowardNegativeF32_TowardNegativeF64) |208 209    encodeFltRoundsToHWTable(HWTowardZero, HWNearestTiesToEven,210                             TowardZeroF32_NearestTiesToEvenF64) |211    encodeFltRoundsToHWTable(HWTowardZero, HWTowardPositive,212                             TowardZeroF32_TowardPositiveF64) |213    encodeFltRoundsToHWTable(HWTowardZero, HWTowardNegative,214                             TowardZeroF32_TowardNegativeF64) |215 216    encodeFltRoundsToHWTable(HWNearestTiesToEven, HWTowardZero,217                             NearestTiesToEvenF32_TowardZeroF64) |218    encodeFltRoundsToHWTable(HWNearestTiesToEven, HWTowardPositive,219                             NearestTiesToEvenF32_TowardPositiveF64) |220    encodeFltRoundsToHWTable(HWNearestTiesToEven, HWTowardNegative,221                             NearestTiesToEvenF32_TowardNegativeF64) |222 223    encodeFltRoundsToHWTable(HWTowardPositive, HWTowardZero,224                             TowardPositiveF32_TowardZeroF64) |225    encodeFltRoundsToHWTable(HWTowardPositive, HWNearestTiesToEven,226                             TowardPositiveF32_NearestTiesToEvenF64) |227    encodeFltRoundsToHWTable(HWTowardPositive, HWTowardNegative,228                             TowardPositiveF32_TowardNegativeF64) |229 230    encodeFltRoundsToHWTable(HWTowardNegative, HWTowardZero,231                             TowardNegativeF32_TowardZeroF64) |232    encodeFltRoundsToHWTable(HWTowardNegative, HWNearestTiesToEven,233                             TowardNegativeF32_NearestTiesToEvenF64) |234    encodeFltRoundsToHWTable(HWTowardNegative, HWTowardPositive,235                             TowardNegativeF32_TowardPositiveF64);236 237/// Read the hardware rounding mode equivalent of a AMDGPUFltRounds value.238static constexpr uint32_t239decodeFltRoundToHWConversionTable(uint64_t FltRoundToHWConversionTable,240                                  uint32_t FltRounds) {241  uint32_t IndexVal = FltRounds;242  if (IndexVal > TowardNegative)243    IndexVal -= ExtendedFltRoundOffset;244  return (FltRoundToHWConversionTable >> (IndexVal << 2)) & 0xf;245}246 247uint32_t AMDGPU::decodeFltRoundToHWConversionTable(uint32_t FltRounds) {248  return ::decodeFltRoundToHWConversionTable(FltRoundToHWConversionTable,249                                             FltRounds);250}251 252static constexpr uint32_t decodeFltRoundToHW(uint32_t FltRounds) {253  return ::decodeFltRoundToHWConversionTable(FltRoundToHWConversionTable,254                                             FltRounds);255}256 257// Verify evaluation of FltRoundToHWConversionTable258 259static_assert(decodeFltRoundToHW(AMDGPUFltRounds::TowardZero) ==260              getModeRegisterRoundMode(HWTowardZero, HWTowardZero));261static_assert(decodeFltRoundToHW(AMDGPUFltRounds::NearestTiesToEven) ==262              getModeRegisterRoundMode(HWNearestTiesToEven,263                                       HWNearestTiesToEven));264static_assert(decodeFltRoundToHW(AMDGPUFltRounds::TowardPositive) ==265              getModeRegisterRoundMode(HWTowardPositive, HWTowardPositive));266static_assert(decodeFltRoundToHW(AMDGPUFltRounds::TowardNegative) ==267              getModeRegisterRoundMode(HWTowardNegative, HWTowardNegative));268 269static_assert(decodeFltRoundToHW(NearestTiesToEvenF32_TowardPositiveF64) ==270              getModeRegisterRoundMode(HWNearestTiesToEven, HWTowardPositive));271static_assert(decodeFltRoundToHW(NearestTiesToEvenF32_TowardNegativeF64) ==272              getModeRegisterRoundMode(HWNearestTiesToEven, HWTowardNegative));273static_assert(decodeFltRoundToHW(NearestTiesToEvenF32_TowardZeroF64) ==274              getModeRegisterRoundMode(HWNearestTiesToEven, HWTowardZero));275 276static_assert(decodeFltRoundToHW(TowardPositiveF32_NearestTiesToEvenF64) ==277              getModeRegisterRoundMode(HWTowardPositive, HWNearestTiesToEven));278static_assert(decodeFltRoundToHW(TowardPositiveF32_TowardNegativeF64) ==279              getModeRegisterRoundMode(HWTowardPositive, HWTowardNegative));280static_assert(decodeFltRoundToHW(TowardPositiveF32_TowardZeroF64) ==281              getModeRegisterRoundMode(HWTowardPositive, HWTowardZero));282 283static_assert(decodeFltRoundToHW(TowardNegativeF32_NearestTiesToEvenF64) ==284              getModeRegisterRoundMode(HWTowardNegative, HWNearestTiesToEven));285static_assert(decodeFltRoundToHW(TowardNegativeF32_TowardPositiveF64) ==286              getModeRegisterRoundMode(HWTowardNegative, HWTowardPositive));287static_assert(decodeFltRoundToHW(TowardNegativeF32_TowardZeroF64) ==288              getModeRegisterRoundMode(HWTowardNegative, HWTowardZero));289 290static_assert(decodeFltRoundToHW(TowardZeroF32_NearestTiesToEvenF64) ==291              getModeRegisterRoundMode(HWTowardZero, HWNearestTiesToEven));292static_assert(decodeFltRoundToHW(TowardZeroF32_TowardPositiveF64) ==293              getModeRegisterRoundMode(HWTowardZero, HWTowardPositive));294static_assert(decodeFltRoundToHW(TowardZeroF32_TowardNegativeF64) ==295              getModeRegisterRoundMode(HWTowardZero, HWTowardNegative));296