1 //===-- SIModeRegisterDefaults.h --------------------------------*- 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-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #ifndef LLVM_LIB_TARGET_AMDGPU_SIMODEREGISTERDEFAULTS_H 10 #define LLVM_LIB_TARGET_AMDGPU_SIMODEREGISTERDEFAULTS_H 11 12 #include "Utils/AMDGPUBaseInfo.h" 13 #include "llvm/ADT/FloatingPointMode.h" 14 15 namespace llvm { 16 17 // Track defaults for fields in the MODE register. 18 struct SIModeRegisterDefaults { 19 /// Floating point opcodes that support exception flag gathering quiet and 20 /// propagate signaling NaN inputs per IEEE 754-2008. Min_dx10 and max_dx10 21 /// become IEEE 754- 2008 compliant due to signaling NaN propagation and 22 /// quieting. 23 bool IEEE : 1; 24 25 /// Used by the vector ALU to force DX10-style treatment of NaNs: when set, 26 /// clamp NaN to zero; otherwise, pass NaN through. 27 bool DX10Clamp : 1; 28 29 /// If this is set, neither input or output denormals are flushed for most f32 30 /// instructions. 31 DenormalMode FP32Denormals; 32 33 /// If this is set, neither input or output denormals are flushed for both f64 34 /// and f16/v2f16 instructions. 35 DenormalMode FP64FP16Denormals; 36 37 SIModeRegisterDefaults() : 38 IEEE(true), 39 DX10Clamp(true), 40 FP32Denormals(DenormalMode::getIEEE()), 41 FP64FP16Denormals(DenormalMode::getIEEE()) {} 42 43 SIModeRegisterDefaults(const Function &F); 44 45 static SIModeRegisterDefaults getDefaultForCallingConv(CallingConv::ID CC) { 46 SIModeRegisterDefaults Mode; 47 Mode.IEEE = !AMDGPU::isShader(CC); 48 return Mode; 49 } 50 51 bool operator==(const SIModeRegisterDefaults Other) const { 52 return IEEE == Other.IEEE && DX10Clamp == Other.DX10Clamp && 53 FP32Denormals == Other.FP32Denormals && 54 FP64FP16Denormals == Other.FP64FP16Denormals; 55 } 56 57 /// Get the encoding value for the FP_DENORM bits of the mode register for the 58 /// FP32 denormal mode. 59 uint32_t fpDenormModeSPValue() const { 60 if (FP32Denormals == DenormalMode::getPreserveSign()) 61 return FP_DENORM_FLUSH_IN_FLUSH_OUT; 62 if (FP32Denormals.Output == DenormalMode::PreserveSign) 63 return FP_DENORM_FLUSH_OUT; 64 if (FP32Denormals.Input == DenormalMode::PreserveSign) 65 return FP_DENORM_FLUSH_IN; 66 return FP_DENORM_FLUSH_NONE; 67 } 68 69 /// Get the encoding value for the FP_DENORM bits of the mode register for the 70 /// FP64/FP16 denormal mode. 71 uint32_t fpDenormModeDPValue() const { 72 if (FP64FP16Denormals == DenormalMode::getPreserveSign()) 73 return FP_DENORM_FLUSH_IN_FLUSH_OUT; 74 if (FP64FP16Denormals.Output == DenormalMode::PreserveSign) 75 return FP_DENORM_FLUSH_OUT; 76 if (FP64FP16Denormals.Input == DenormalMode::PreserveSign) 77 return FP_DENORM_FLUSH_IN; 78 return FP_DENORM_FLUSH_NONE; 79 } 80 81 // FIXME: Inlining should be OK for dx10-clamp, since the caller's mode should 82 // be able to override. 83 bool isInlineCompatible(SIModeRegisterDefaults CalleeMode) const { 84 return DX10Clamp == CalleeMode.DX10Clamp && IEEE == CalleeMode.IEEE; 85 } 86 }; 87 88 } // end namespace llvm 89 90 #endif // LLVM_LIB_TARGET_AMDGPU_SIMODEREGISTERDEFAULTS_H 91