The complete ASL owner is shown directly below.
12pure func HardwareNumericTypeHasSubnormals(data_type: TileDataType) => boolean3begin4 case data_type of5 when TileDataType_FP64, TileDataType_FP32, TileDataType_TF32,6 TileDataType_HF32, TileDataType_FP16, TileDataType_BF16,7 TileDataType_HiF8, TileDataType_E4M3, TileDataType_E5M2,8 TileDataType_E3M2, TileDataType_E2M3 => return TRUE;9 otherwise => return FALSE;10 end;11end;12
13pure func HardwareNumericInputSubnormalRule(data_type: TileDataType)14 => NumericInputSubnormalRule15begin16 if HardwareNumericTypeHasSubnormals(data_type) then17 return NumericInputSubnormal_Preserve;18 else return NumericInputSubnormal_NotApplicable;19 end;20end;21
22pure func HardwareNumericResultSubnormalRule(data_type: TileDataType)23 => NumericResultSubnormalRule24begin25 if HardwareNumericTypeHasSubnormals(data_type) then26 return NumericResultSubnormal_GradualUnderflow;27 else return NumericResultSubnormal_NotApplicable;28 end;29end;30
31pure func HardwareNumericTininessDetectionRule(data_type: TileDataType)32 => NumericTininessDetectionRule33begin34 if HardwareNumericTypeHasSubnormals(data_type) then35 return NumericTininessDetection_AfterRounding;36 else return NumericTininessDetection_NotApplicable;37 end;38end;39
40414243pure func HardwareNumericSubnormalConfigurationValid(flush_to_zero: boolean,44 denormals_are_zero: boolean,45 operation_override: boolean)46 => boolean47begin48 return !flush_to_zero && !denormals_are_zero && !operation_override;49end;50
515253pure func HardwareNumericSubnormalBoundaries(data_type: TileDataType)54 => (boolean, Word, Word, Word)55begin56 case data_type of57 when TileDataType_FP64 =>58 return (TRUE, Zeros{PTO_XLEN} + 0x1,59 Zeros{PTO_XLEN} + 0x000fffffffffffff,60 Zeros{PTO_XLEN} + 0x0010000000000000);61 when TileDataType_FP32 =>62 return (TRUE, Zeros{PTO_XLEN} + 0x1,63 Zeros{PTO_XLEN} + 0x007fffff,64 Zeros{PTO_XLEN} + 0x00800000);65 when TileDataType_TF32 =>66 return (TRUE, Zeros{PTO_XLEN} + 0x00002000,67 Zeros{PTO_XLEN} + 0x007fe000,68 Zeros{PTO_XLEN} + 0x00800000);69 when TileDataType_HF32 =>70 return (TRUE, Zeros{PTO_XLEN} + 0x00001000,71 Zeros{PTO_XLEN} + 0x007ff000,72 Zeros{PTO_XLEN} + 0x00800000);73 when TileDataType_FP16 =>74 return (TRUE, Zeros{PTO_XLEN} + 0x1,75 Zeros{PTO_XLEN} + 0x03ff,76 Zeros{PTO_XLEN} + 0x0400);77 when TileDataType_BF16 =>78 return (TRUE, Zeros{PTO_XLEN} + 0x1,79 Zeros{PTO_XLEN} + 0x007f,80 Zeros{PTO_XLEN} + 0x0080);81 when TileDataType_HiF8 =>82 return (TRUE, Zeros{PTO_XLEN} + 0x01,83 Zeros{PTO_XLEN} + 0x07,84 Zeros{PTO_XLEN} + 0x08);85 when TileDataType_E4M3 =>86 return (TRUE, Zeros{PTO_XLEN} + 0x01,87 Zeros{PTO_XLEN} + 0x07,88 Zeros{PTO_XLEN} + 0x08);89 when TileDataType_E5M2, TileDataType_E3M2 =>90 return (TRUE, Zeros{PTO_XLEN} + 0x01,91 Zeros{PTO_XLEN} + 0x03,92 Zeros{PTO_XLEN} + 0x04);93 when TileDataType_E2M3 =>94 return (TRUE, Zeros{PTO_XLEN} + 0x01,95 Zeros{PTO_XLEN} + 0x07,96 Zeros{PTO_XLEN} + 0x08);97 otherwise =>98 return (FALSE, Zeros{PTO_XLEN}, Zeros{PTO_XLEN},99 Zeros{PTO_XLEN});100 end;101end;102
103pure func NumericValueClassFromFiniteSign(sign: bits(1), zero: boolean,104 subnormal: boolean)105 => NumericValueClass106begin107 if zero then108 if sign == '1' then return NumericValue_NegativeZero;109 else return NumericValue_PositiveZero;110 end;111 elsif subnormal then112 if sign == '1' then return NumericValue_NegativeSubnormal;113 else return NumericValue_PositiveSubnormal;114 end;115 elsif sign == '1' then return NumericValue_NegativeNormal;116 else return NumericValue_PositiveNormal;117 end;118end;119
120121122123pure func TileNumericEncodingValid(data_type: TileDataType,124 value: Word) => boolean125begin126 case data_type of127 when TileDataType_TF32 => return TF32EncodingValid(value[31:0]);128 when TileDataType_HF32 => return HF32EncodingValid(value[31:0]);129 when TileDataType_E3M2 => return E3M2EncodingValid(value[7:0]);130 when TileDataType_E2M3 => return E2M3EncodingValid(value[7:0]);131 otherwise => return TRUE;132 end;133end;134
135pure func ClassifySignedInteger(value: Word, sign_bit: integer {3,7,15,31,63})136 => NumericValueClass137begin138 var zero = FALSE;139 case sign_bit of140 when 3 => zero = value[3:0] == Zeros{4};141 when 7 => zero = value[7:0] == Zeros{8};142 when 15 => zero = value[15:0] == Zeros{16};143 when 31 => zero = value[31:0] == Zeros{32};144 when 63 => zero = value == Zeros{PTO_XLEN};145 end;146 if zero then return NumericValue_PositiveZero;147 elsif value[sign_bit] == '1' then return NumericValue_NegativeNormal;148 else return NumericValue_PositiveNormal;149 end;150end;151
152pure func ClassifyUnsignedInteger(value: Word, width: integer {4,8,16,32,64})153 => NumericValueClass154begin155 var zero = FALSE;156 case width of157 when 4 => zero = value[3:0] == Zeros{4};158 when 8 => zero = value[7:0] == Zeros{8};159 when 16 => zero = value[15:0] == Zeros{16};160 when 32 => zero = value[31:0] == Zeros{32};161 when 64 => zero = value == Zeros{PTO_XLEN};162 end;163 if zero then return NumericValue_PositiveZero;164 else return NumericValue_PositiveNormal;165 end;166end;167
168pure func TileNumericValueClass(data_type: TileDataType,169 value: Word) => NumericValueClass170begin171 if !TileNumericEncodingValid(data_type, value) then172 return NumericValue_InvalidEncoding;173 end;174 case data_type of175 when TileDataType_FP64 => return ClassifyFP64(value);176 when TileDataType_FP32 => return ClassifyFP32(value[31:0]);177 when TileDataType_TF32 => return ClassifyTF32(value[31:0]);178 when TileDataType_HF32 => return ClassifyHF32(value[31:0]);179 when TileDataType_FP16 => return ClassifyFP16(value[15:0]);180 when TileDataType_BF16 => return ClassifyBF16(value[15:0]);181 when TileDataType_HiF8 => return ClassifyHiF8(value[7:0]);182 when TileDataType_E4M3 => return ClassifyE4M3(value[7:0]);183 when TileDataType_E5M2 => return ClassifyE5M2(value[7:0]);184 when TileDataType_E3M2 => return ClassifyE3M2(value[7:0]);185 when TileDataType_E2M3 => return ClassifyE2M3(value[7:0]);186 when TileDataType_E2M1X2 => return ClassifyE2M1X2(value);187 when TileDataType_E1M2X2 => return ClassifyE1M2X2(value);188 when TileDataType_E8M0 => return ClassifyE8M0(value[7:0]);189 when TileDataType_HiF4X2 => return ClassifyHiF4X2(value);190 when TileDataType_S64 => return ClassifySignedInteger(value, 63);191 when TileDataType_S32 => return ClassifySignedInteger(value, 31);192 when TileDataType_S16 => return ClassifySignedInteger(value, 15);193 when TileDataType_S8 => return ClassifySignedInteger(value, 7);194 when TileDataType_S4X2 => return ClassifySignedInteger(value, 3);195 when TileDataType_U64 => return ClassifyUnsignedInteger(value, 64);196 when TileDataType_U32 => return ClassifyUnsignedInteger(value, 32);197 when TileDataType_U16 => return ClassifyUnsignedInteger(value, 16);198 when TileDataType_U8 => return ClassifyUnsignedInteger(value, 8);199 when TileDataType_U4X2 => return ClassifyUnsignedInteger(value, 4);200 end;201end;202
203pure func TileNumericCanonicalNaN(data_type: TileDataType) => (boolean, Word)204begin205 case data_type of206 when TileDataType_FP64 => return (TRUE, FP64CanonicalNaN());207 when TileDataType_FP32 => return (TRUE, FP32CanonicalNaN());208 when TileDataType_TF32 => return (TRUE, TF32CanonicalNaN());209 when TileDataType_HF32 => return (TRUE, HF32CanonicalNaN());210 when TileDataType_FP16 => return (TRUE, FP16CanonicalNaN());211 when TileDataType_BF16 => return (TRUE, BF16CanonicalNaN());212 when TileDataType_HiF8 => return (TRUE, HiF8CanonicalNaN());213 when TileDataType_E4M3 => return (TRUE, E4M3CanonicalNaN());214 when TileDataType_E5M2 => return (TRUE, E5M2CanonicalNaN());215 when TileDataType_E8M0 => return (TRUE, E8M0CanonicalNaN());216 otherwise => return (FALSE, Zeros{PTO_XLEN});217 end;218end;219
220221222223224pure func HardwareNumericCanonicalNaNResult(data_type: TileDataType)225 => (boolean, Word)226begin227 return TileNumericCanonicalNaN(data_type);228end;229
230231232233234235pure func HardwareNumericMixedExpdifDiscriminator(left: Word, right: Word)236 => (boolean, Word)237begin238 if left == (Zeros{PTO_XLEN} + 0x3c000000) &&239 right == (Zeros{PTO_XLEN} + 0x33800000) then240 return (TRUE, Zeros{PTO_XLEN} + 0x3f810100);241 elsif left == (Zeros{PTO_XLEN} + 0x3f800000) &&242 right == (Zeros{PTO_XLEN} + 0x3b000000) then243 return (TRUE, Zeros{PTO_XLEN} + 0x402da16e);244 end;245 return (FALSE, Zeros{PTO_XLEN});246end;247
248pure func HardwareNumericSignedZeroEncodings(data_type: TileDataType)249 => (boolean, Word, Word)250begin251 case data_type of252 when TileDataType_FP64 =>253 let (positive, negative) = FP64SignedZeroEncodings();254 return (TRUE, positive, negative);255 when TileDataType_FP32 =>256 let (positive, negative) = FP32SignedZeroEncodings();257 return (TRUE, positive, negative);258 when TileDataType_TF32 =>259 let (positive, negative) = TF32SignedZeroEncodings();260 return (TRUE, positive, negative);261 when TileDataType_HF32 =>262 let (positive, negative) = HF32SignedZeroEncodings();263 return (TRUE, positive, negative);264 when TileDataType_FP16 =>265 let (positive, negative) = FP16SignedZeroEncodings();266 return (TRUE, positive, negative);267 when TileDataType_BF16 =>268 let (positive, negative) = BF16SignedZeroEncodings();269 return (TRUE, positive, negative);270 when TileDataType_E4M3 =>271 let (positive, negative) = E4M3SignedZeroEncodings();272 return (TRUE, positive, negative);273 when TileDataType_E5M2 =>274 let (positive, negative) = E5M2SignedZeroEncodings();275 return (TRUE, positive, negative);276 when TileDataType_E3M2 =>277 let (positive, negative) = E3M2SignedZeroEncodings();278 return (TRUE, positive, negative);279 when TileDataType_E2M3 =>280 let (positive, negative) = E2M3SignedZeroEncodings();281 return (TRUE, positive, negative);282 when TileDataType_E2M1X2 =>283 let (positive, negative) = E2M1X2SignedZeroEncodings();284 return (TRUE, positive, negative);285 when TileDataType_E1M2X2 =>286 let (positive, negative) = E1M2X2SignedZeroEncodings();287 return (TRUE, positive, negative);288 when TileDataType_HiF4X2 =>289 let (positive, negative) = HiF4X2SignedZeroEncodings();290 return (TRUE, positive, negative);291 otherwise => return (FALSE, Zeros{PTO_XLEN}, Zeros{PTO_XLEN});292 end;293end;294
295296297pure func HardwareNumericComparisonSpecial(298 comparison: TileComparison, data_type: TileDataType,299 left: Word, right: Word) => (boolean, Word, boolean)300begin301 let left_class = TileNumericValueClass(data_type, left);302 let right_class = TileNumericValueClass(data_type, right);303 if left_class == NumericValue_InvalidEncoding ||304 right_class == NumericValue_InvalidEncoding then305 return (FALSE, Zeros{PTO_XLEN}, FALSE);306 end;307 let left_nan = NumericValueClassIsNaN(left_class);308 let right_nan = NumericValueClassIsNaN(right_class);309 let invalid = left_class == NumericValue_SignalingNaN ||310 right_class == NumericValue_SignalingNaN;311 if left_nan || right_nan then312 if comparison == TileComparison_NE then313 return (TRUE, Zeros{PTO_XLEN} + 1, invalid);314 else return (TRUE, Zeros{PTO_XLEN}, invalid);315 end;316 end;317 if NumericValueClassIsZero(left_class) &&318 NumericValueClassIsZero(right_class) then319 if comparison == TileComparison_EQ || comparison == TileComparison_LE ||320 comparison == TileComparison_GE then321 return (TRUE, Zeros{PTO_XLEN} + 1, FALSE);322 else return (TRUE, Zeros{PTO_XLEN}, FALSE);323 end;324 end;325 return (FALSE, Zeros{PTO_XLEN}, FALSE);326end;327
328329330331pure func HardwareNumericMinMaxSpecial(332 maximum: boolean, data_type: TileDataType,333 left: Word, right: Word) => (boolean, Word, boolean)334begin335 let left_class = TileNumericValueClass(data_type, left);336 let right_class = TileNumericValueClass(data_type, right);337 if left_class == NumericValue_InvalidEncoding ||338 right_class == NumericValue_InvalidEncoding then339 return (FALSE, Zeros{PTO_XLEN}, FALSE);340 end;341 let left_nan = NumericValueClassIsNaN(left_class);342 let right_nan = NumericValueClassIsNaN(right_class);343 let invalid = left_class == NumericValue_SignalingNaN ||344 right_class == NumericValue_SignalingNaN;345 if left_nan && right_nan then346 let (available, canonical) =347 HardwareNumericCanonicalNaNResult(data_type);348 assert available;349 return (TRUE, canonical, invalid);350 elsif left_nan then return (TRUE, right, invalid);351 elsif right_nan then return (TRUE, left, invalid);352 end;353 if NumericValueClassIsZero(left_class) &&354 NumericValueClassIsZero(right_class) then355 if maximum && left_class == NumericValue_NegativeZero &&356 right_class == NumericValue_NegativeZero then357 return (TRUE, left, FALSE);358 elsif maximum then return (TRUE, Zeros{PTO_XLEN}, FALSE);359 elsif left_class == NumericValue_NegativeZero then360 return (TRUE, left, FALSE);361 elsif right_class == NumericValue_NegativeZero then362 return (TRUE, right, FALSE);363 else return (TRUE, Zeros{PTO_XLEN}, FALSE);364 end;365 end;366 return (FALSE, Zeros{PTO_XLEN}, FALSE);367end;368