| 438 | } |
| 439 | |
| 440 | fn emit<M: MacroAssembler>( |
| 441 | &mut self, |
| 442 | masm: &mut M, |
| 443 | context: &mut CodeGenContext<Emission>, |
| 444 | ) -> Result<()> { |
| 445 | use ControlStackFrame::*; |
| 446 | |
| 447 | // Do not perform any emissions if we are in an unreachable state. |
| 448 | if !context.reachable { |
| 449 | return Ok(()); |
| 450 | } |
| 451 | |
| 452 | match *self { |
| 453 | If { cont, .. } => { |
| 454 | // Pop the condition value. |
| 455 | // Because in the case of Self::If, Self::init, will top the |
| 456 | // branch params, we exclude any result registers from being |
| 457 | // used as the branch test. |
| 458 | let top = context.without::<Result<TypedReg>, _, _>( |
| 459 | self.params::<M>()?.regs(), |
| 460 | masm, |
| 461 | |cx, masm| cx.pop_to_reg(masm, None), |
| 462 | )??; |
| 463 | self.init(masm, context)?; |
| 464 | masm.branch( |
| 465 | IntCmpKind::Eq, |
| 466 | top.reg, |
| 467 | top.reg.into(), |
| 468 | cont, |
| 469 | OperandSize::S32, |
| 470 | )?; |
| 471 | context.free_reg(top); |
| 472 | Ok(()) |
| 473 | } |
| 474 | Block { .. } => self.init(masm, context), |
| 475 | Loop { head, .. } => { |
| 476 | self.init(masm, context)?; |
| 477 | masm.bind(head)?; |
| 478 | Ok(()) |
| 479 | } |
| 480 | _ => Err(format_err!(CodeGenError::if_control_frame_expected())), |
| 481 | } |
| 482 | } |
| 483 | |
| 484 | /// Handles the else branch if the current control stack frame is |
| 485 | /// [`ControlStackFrame::If`]. |