This Operation comes directly from the instruction owner; the page does not rewrite its behavior.
14pure func HardwareTCVTE8M0SourceTypeSupported(15 source_type: TileDataType) => boolean16begin17 return source_type == TileDataType_FP16 ||18 source_type == TileDataType_BF16 ||19 source_type == TileDataType_FP32;20end;21
22pure func HardwareTCVTTypePairSupported(23 source_type: TileDataType,24 destination_type: TileDataType) => boolean25begin26 if destination_type == TileDataType_E8M0 then27 return HardwareTCVTE8M0SourceTypeSupported(source_type);28 end;29 return TRUE;30end;31
32pure func ReferenceE8M0HighestSetBit(33 significand: Word) => integer {0..63}34begin35 assert !IsZero(significand);36 var highest: integer {0..63} = 0;37 for position = 0 to 63 do38 if significand[position] == '1' then39 highest = position as integer {0..63};40 end;41 end;42 return highest;43end;44
45pure func ReferenceE8M0RoundExponent(46 significand: Word,47 exponent: integer {-1074..1023},48 mode: NumericRoundingMode) => (integer {-149..128}, boolean)49begin50 let highest = ReferenceE8M0HighestSetBit(significand);51 let floor_candidate = exponent + highest;52 assert -149 <= floor_candidate && floor_candidate <= 127;53 let floor_exponent = floor_candidate as integer {-149..127};54 let exact_power = significand ==55 LSL(Zeros{PTO_XLEN} + 1, highest);56 if exact_power then57 return (floor_exponent, TRUE);58 end;59
60 let ceiling_exponent = (floor_exponent + 1) as integer {-148..128};61 if mode == NumericRound_RTM then62 return (floor_exponent, FALSE);63 elsif mode == NumericRound_RTP then64 return (ceiling_exponent, FALSE);65 elsif mode == NumericRound_RTZ then66 if floor_exponent < 0 then67 return (ceiling_exponent, FALSE);68 else return (floor_exponent, FALSE);69 end;70 elsif mode == NumericRound_RTO then71 if floor_exponent MOD 2 != 0 then72 return (floor_exponent, FALSE);73 else return (ceiling_exponent, FALSE);74 end;75 end;76
77 let square = MultiplyWord(significand, significand);78 let boundary_shift = 2 * highest + 1;79 assert boundary_shift <= 127;80 let boundary = LSL(81 Zeros{PTO_XLEN} + 1,82 boundary_shift as integer {0..127});83 if UInt(square) < UInt(boundary) then84 return (floor_exponent, FALSE);85 elsif UInt(square) > UInt(boundary) then86 return (ceiling_exponent, FALSE);87 elsif mode == NumericRound_RNE then88 if floor_exponent MOD 2 == 0 then89 return (floor_exponent, FALSE);90 else return (ceiling_exponent, FALSE);91 end;92 elsif mode == NumericRound_RNA then93 if floor_exponent < 0 then94 return (floor_exponent, FALSE);95 else return (ceiling_exponent, FALSE);96 end;97 else98 assert mode == NumericRound_RHB;99 return (ceiling_exponent, FALSE);100 end;101end;102
103func ReferenceFloatToE8M0(104 value: Word,105 source_type: TileDataType,106 control: NumericExecutionControl) => (Word, bits(5))107begin108 assert HardwareTCVTE8M0SourceTypeSupported(source_type);109 let value_class = TileNumericValueClass(source_type, value);110 if value_class == NumericValue_InvalidEncoding ||111 NumericValueClassIsNaN(value_class) ||112 NumericValueClassIsZero(value_class) ||113 value_class == NumericValue_NegativeInfinity ||114 value_class == NumericValue_NegativeNormal ||115 value_class == NumericValue_NegativeSubnormal then116 return (Zeros{PTO_XLEN} + 0xff, Zeros{5} + 0x01);117 elsif value_class == NumericValue_PositiveInfinity then118 return (119 if control.saturating then Zeros{PTO_XLEN} + 0xfe120 else Zeros{PTO_XLEN} + 0xff,121 Zeros{5} + 0x14);122 end;123
124 let (available, negative, significand, exponent) =125 TileNumericFiniteDecomposition(source_type, value);126 assert available && !negative && !IsZero(significand);127 let highest = ReferenceE8M0HighestSetBit(significand);128 let floor_candidate = exponent + highest;129 assert -149 <= floor_candidate && floor_candidate <= 127;130 let floor_exponent = floor_candidate as integer {-149..127};131 let exact_power = significand ==132 LSL(Zeros{PTO_XLEN} + 1, highest);133 if floor_exponent < -127 then134 return (135 if control.saturating then Zeros{PTO_XLEN}136 else Zeros{PTO_XLEN} + 0xff,137 Zeros{5} + 0x18);138 elsif floor_exponent == 127 && !exact_power then139 return (140 if control.saturating then Zeros{PTO_XLEN} + 0xfe141 else Zeros{PTO_XLEN} + 0xff,142 Zeros{5} + 0x14);143 end;144
145 let (rounded_exponent, exact) = ReferenceE8M0RoundExponent(146 significand, exponent, control.rounding_mode);147 assert -127 <= rounded_exponent && rounded_exponent <= 127;148 let code = (rounded_exponent + 127) as integer {0..254};149 return (150 Zeros{PTO_XLEN} + code,151 if exact then Zeros{5} else Zeros{5} + 0x10);152end;153
154implementation func TileProfileConvert(155 value: Word,156 source_type: TileDataType,157 destination_type: TileDataType,158 control: NumericExecutionControl) => (Word, bits(5))159begin160 if destination_type == TileDataType_E8M0 then161 return ReferenceFloatToE8M0(value, source_type, control);162 elsif !TileDataTypeIsFloating(destination_type) then163 return (164 NormalizeTileInteger(value, destination_type),165 Zeros{5});166 end;167 return (value, Zeros{5});168end;
View the complete ASL owner
12
3456789101112
1314pure func HardwareTCVTE8M0SourceTypeSupported(15 source_type: TileDataType) => boolean16begin17 return source_type == TileDataType_FP16 ||18 source_type == TileDataType_BF16 ||19 source_type == TileDataType_FP32;20end;21
22pure func HardwareTCVTTypePairSupported(23 source_type: TileDataType,24 destination_type: TileDataType) => boolean25begin26 if destination_type == TileDataType_E8M0 then27 return HardwareTCVTE8M0SourceTypeSupported(source_type);28 end;29 return TRUE;30end;31
32pure func ReferenceE8M0HighestSetBit(33 significand: Word) => integer {0..63}34begin35 assert !IsZero(significand);36 var highest: integer {0..63} = 0;37 for position = 0 to 63 do38 if significand[position] == '1' then39 highest = position as integer {0..63};40 end;41 end;42 return highest;43end;44
45pure func ReferenceE8M0RoundExponent(46 significand: Word,47 exponent: integer {-1074..1023},48 mode: NumericRoundingMode) => (integer {-149..128}, boolean)49begin50 let highest = ReferenceE8M0HighestSetBit(significand);51 let floor_candidate = exponent + highest;52 assert -149 <= floor_candidate && floor_candidate <= 127;53 let floor_exponent = floor_candidate as integer {-149..127};54 let exact_power = significand ==55 LSL(Zeros{PTO_XLEN} + 1, highest);56 if exact_power then57 return (floor_exponent, TRUE);58 end;59
60 let ceiling_exponent = (floor_exponent + 1) as integer {-148..128};61 if mode == NumericRound_RTM then62 return (floor_exponent, FALSE);63 elsif mode == NumericRound_RTP then64 return (ceiling_exponent, FALSE);65 elsif mode == NumericRound_RTZ then66 if floor_exponent < 0 then67 return (ceiling_exponent, FALSE);68 else return (floor_exponent, FALSE);69 end;70 elsif mode == NumericRound_RTO then71 if floor_exponent MOD 2 != 0 then72 return (floor_exponent, FALSE);73 else return (ceiling_exponent, FALSE);74 end;75 end;76
77 let square = MultiplyWord(significand, significand);78 let boundary_shift = 2 * highest + 1;79 assert boundary_shift <= 127;80 let boundary = LSL(81 Zeros{PTO_XLEN} + 1,82 boundary_shift as integer {0..127});83 if UInt(square) < UInt(boundary) then84 return (floor_exponent, FALSE);85 elsif UInt(square) > UInt(boundary) then86 return (ceiling_exponent, FALSE);87 elsif mode == NumericRound_RNE then88 if floor_exponent MOD 2 == 0 then89 return (floor_exponent, FALSE);90 else return (ceiling_exponent, FALSE);91 end;92 elsif mode == NumericRound_RNA then93 if floor_exponent < 0 then94 return (floor_exponent, FALSE);95 else return (ceiling_exponent, FALSE);96 end;97 else98 assert mode == NumericRound_RHB;99 return (ceiling_exponent, FALSE);100 end;101end;102
103func ReferenceFloatToE8M0(104 value: Word,105 source_type: TileDataType,106 control: NumericExecutionControl) => (Word, bits(5))107begin108 assert HardwareTCVTE8M0SourceTypeSupported(source_type);109 let value_class = TileNumericValueClass(source_type, value);110 if value_class == NumericValue_InvalidEncoding ||111 NumericValueClassIsNaN(value_class) ||112 NumericValueClassIsZero(value_class) ||113 value_class == NumericValue_NegativeInfinity ||114 value_class == NumericValue_NegativeNormal ||115 value_class == NumericValue_NegativeSubnormal then116 return (Zeros{PTO_XLEN} + 0xff, Zeros{5} + 0x01);117 elsif value_class == NumericValue_PositiveInfinity then118 return (119 if control.saturating then Zeros{PTO_XLEN} + 0xfe120 else Zeros{PTO_XLEN} + 0xff,121 Zeros{5} + 0x14);122 end;123
124 let (available, negative, significand, exponent) =125 TileNumericFiniteDecomposition(source_type, value);126 assert available && !negative && !IsZero(significand);127 let highest = ReferenceE8M0HighestSetBit(significand);128 let floor_candidate = exponent + highest;129 assert -149 <= floor_candidate && floor_candidate <= 127;130 let floor_exponent = floor_candidate as integer {-149..127};131 let exact_power = significand ==132 LSL(Zeros{PTO_XLEN} + 1, highest);133 if floor_exponent < -127 then134 return (135 if control.saturating then Zeros{PTO_XLEN}136 else Zeros{PTO_XLEN} + 0xff,137 Zeros{5} + 0x18);138 elsif floor_exponent == 127 && !exact_power then139 return (140 if control.saturating then Zeros{PTO_XLEN} + 0xfe141 else Zeros{PTO_XLEN} + 0xff,142 Zeros{5} + 0x14);143 end;144
145 let (rounded_exponent, exact) = ReferenceE8M0RoundExponent(146 significand, exponent, control.rounding_mode);147 assert -127 <= rounded_exponent && rounded_exponent <= 127;148 let code = (rounded_exponent + 127) as integer {0..254};149 return (150 Zeros{PTO_XLEN} + code,151 if exact then Zeros{5} else Zeros{5} + 0x10);152end;153
154implementation func TileProfileConvert(155 value: Word,156 source_type: TileDataType,157 destination_type: TileDataType,158 control: NumericExecutionControl) => (Word, bits(5))159begin160 if destination_type == TileDataType_E8M0 then161 return ReferenceFloatToE8M0(value, source_type, control);162 elsif !TileDataTypeIsFloating(destination_type) then163 return (164 NormalizeTileInteger(value, destination_type),165 Zeros{5});166 end;167 return (value, Zeros{5});168end;169170