MCPcopy Index your code
hub / github.com/RustPython/RustPython / compile_fpow

Method compile_fpow

crates/jit/src/instructions.rs:1157–1374  ·  view source on GitHub ↗

Computes the power function a^b (f_pow) for f64 values using double–double arithmetic for high precision. It handles different cases for the base 'a': - For a > 0: Computes exp(b * ln(a)). - For a == 0: Handles special cases for 0^b, including returning 0, 1, or a domain error. - For a < 0: Allows only an integer exponent b and adjusts the sign if b is odd.

(&mut self, a: Value, b: Value)

Source from the content-addressed store, hash-verified

1155 /// - For a == 0: Handles special cases for 0^b, including returning 0, 1, or a domain error.
1156 /// - For a < 0: Allows only an integer exponent b and adjusts the sign if b is odd.
1157 fn compile_fpow(&mut self, a: Value, b: Value) -> Value {
1158 let f64_ty = types::F64;
1159 let i64_ty = types::I64;
1160 let zero_f = self.builder.ins().f64const(0.0);
1161 let one_f = self.builder.ins().f64const(1.0);
1162 let nan_f = self.builder.ins().f64const(f64::NAN);
1163 let inf_f = self.builder.ins().f64const(f64::INFINITY);
1164 let neg_inf_f = self.builder.ins().f64const(f64::NEG_INFINITY);
1165
1166 // Merge block for final result.
1167 let merge_block = self.builder.create_block();
1168 self.builder.append_block_param(merge_block, f64_ty);
1169
1170 // --- Edge Case 1: b == 0.0 → return 1.0
1171 let cmp_b_zero = self.builder.ins().fcmp(FloatCC::Equal, b, zero_f);
1172 let b_zero_block = self.builder.create_block();
1173 let continue_block = self.builder.create_block();
1174 self.builder
1175 .ins()
1176 .brif(cmp_b_zero, b_zero_block, &[], continue_block, &[]);
1177 self.builder.switch_to_block(b_zero_block);
1178 self.builder.ins().jump(merge_block, &[one_f.into()]);
1179 self.builder.switch_to_block(continue_block);
1180
1181 // --- Edge Case 2: b is NaN → return NaN
1182 let cmp_b_nan = self.builder.ins().fcmp(FloatCC::Unordered, b, b);
1183 let b_nan_block = self.builder.create_block();
1184 let continue_block2 = self.builder.create_block();
1185 self.builder
1186 .ins()
1187 .brif(cmp_b_nan, b_nan_block, &[], continue_block2, &[]);
1188 self.builder.switch_to_block(b_nan_block);
1189 self.builder.ins().jump(merge_block, &[nan_f.into()]);
1190 self.builder.switch_to_block(continue_block2);
1191
1192 // --- Edge Case 3: a == 0.0 → return 0.0
1193 let cmp_a_zero = self.builder.ins().fcmp(FloatCC::Equal, a, zero_f);
1194 let a_zero_block = self.builder.create_block();
1195 let continue_block3 = self.builder.create_block();
1196 self.builder
1197 .ins()
1198 .brif(cmp_a_zero, a_zero_block, &[], continue_block3, &[]);
1199 self.builder.switch_to_block(a_zero_block);
1200 self.builder.ins().jump(merge_block, &[zero_f.into()]);
1201 self.builder.switch_to_block(continue_block3);
1202
1203 // --- Edge Case 4: a is NaN → return NaN
1204 let cmp_a_nan = self.builder.ins().fcmp(FloatCC::Unordered, a, a);
1205 let a_nan_block = self.builder.create_block();
1206 let continue_block4 = self.builder.create_block();
1207 self.builder
1208 .ins()
1209 .brif(cmp_a_nan, a_nan_block, &[], continue_block4, &[]);
1210 self.builder.switch_to_block(a_nan_block);
1211 self.builder.ins().jump(merge_block, &[nan_f.into()]);
1212 self.builder.switch_to_block(continue_block4);
1213
1214 // --- Edge Case 5: b == +infinity → return +infinity

Callers 1

add_instructionMethod · 0.80

Calls 8

insMethod · 0.80
switch_to_blockMethod · 0.80
jumpMethod · 0.80
dd_lnMethod · 0.80
dd_from_valueMethod · 0.80
dd_mulMethod · 0.80
dd_expMethod · 0.80
dd_to_f64Method · 0.80

Tested by

no test coverage detected