| 452 | } |
| 453 | |
| 454 | pub fn bitselect(&mut self, mut control: JitTemp, mut left: JitTemp, mut right: JitTemp) -> JitTemp { |
| 455 | use JitTemp::*; |
| 456 | let biggest = max(control.width(), max(left.width(), right.width())); |
| 457 | println!("bitselect {:?} {:?} {:?} (biggest={})", control, left, right, biggest); |
| 458 | control = control.zero_extend(self.builder, biggest); |
| 459 | left = left.zero_extend(self.builder, biggest); |
| 460 | right = right.zero_extend(self.builder, biggest); |
| 461 | // bitselect doesn't have a set flags version |
| 462 | if control.is_const() { |
| 463 | let fixed_control = control.clone().into_usize(self.builder).unwrap(); |
| 464 | match fixed_control { |
| 465 | //bitselect(0, left, right) => right |
| 466 | 0 => return right, |
| 467 | //bitselect(!0, left, right) => left |
| 468 | const { !0 as usize } => return left, |
| 469 | _ => (), |
| 470 | }; |
| 471 | } |
| 472 | if left.is_const() { |
| 473 | let fixed_left = left.clone().into_usize(self.builder).unwrap(); |
| 474 | match fixed_left { |
| 475 | //bitselect(control, 0, right) => !control & right |
| 476 | 0 => { |
| 477 | let ncontrol = self.bnot(control); |
| 478 | return self.band(ncontrol, right) |
| 479 | }, |
| 480 | _ => () |
| 481 | }; |
| 482 | } |
| 483 | if right.is_const() { |
| 484 | let fixed_right = right.clone().into_usize(self.builder).unwrap(); |
| 485 | match fixed_right { |
| 486 | //bitselect(control, left, 0) => control & left |
| 487 | 0 => return self.band(control, left), |
| 488 | _ => () |
| 489 | } |
| 490 | } |
| 491 | match (control, left, right) { |
| 492 | (control, left, right) if control.is_const() && left.is_const() && right.is_const() => { |
| 493 | let true_mask = self.band(control.clone(), left); |
| 494 | let not_control = self.bnot(control); |
| 495 | let false_mask = self.band(not_control, right); |
| 496 | self.bor(true_mask, false_mask) |
| 497 | }, |
| 498 | (control @ _, Value(val_left, typ_left), Value(val_right, _)) => { |
| 499 | let control = control.into_ssa(self.int, self.builder); |
| 500 | Value(self.builder.ins().bitselect(control, val_left, val_right), typ_left) |
| 501 | }, |
| 502 | (control, left, right) => |
| 503 | unimplemented!("unimplemented bitselect {:?} {:?} {:?}", control, left, right) |
| 504 | |
| 505 | } |
| 506 | } |
| 507 | |
| 508 | pub fn bnot(&mut self, val: JitTemp) -> JitTemp { |
| 509 | use JitTemp::*; |