Parse the operands following the instruction opcode. This depends on the format of the opcode.
(
&mut self,
ctx: &mut Context,
opcode: Opcode,
explicit_control_type: Option<Type>,
)
| 2662 | // Parse the operands following the instruction opcode. |
| 2663 | // This depends on the format of the opcode. |
| 2664 | fn parse_inst_operands( |
| 2665 | &mut self, |
| 2666 | ctx: &mut Context, |
| 2667 | opcode: Opcode, |
| 2668 | explicit_control_type: Option<Type>, |
| 2669 | ) -> ParseResult<InstructionData> { |
| 2670 | let idata = match opcode.format() { |
| 2671 | InstructionFormat::Unary => InstructionData::Unary { |
| 2672 | opcode, |
| 2673 | arg: self.match_value("expected SSA value operand")?, |
| 2674 | }, |
| 2675 | InstructionFormat::UnaryImm => { |
| 2676 | let msg = |bits| format!("expected immediate {bits}-bit integer operand"); |
| 2677 | let unsigned = match explicit_control_type { |
| 2678 | Some(types::I8) => self.match_imm8(&msg(8))? as u8 as i64, |
| 2679 | Some(types::I16) => self.match_imm16(&msg(16))? as u16 as i64, |
| 2680 | Some(types::I32) => self.match_imm32(&msg(32))? as u32 as i64, |
| 2681 | Some(types::I64) => self.match_imm64(&msg(64))?.bits(), |
| 2682 | _ => { |
| 2683 | return err!( |
| 2684 | self.loc, |
| 2685 | "expected one of the following type: i8, i16, i32 or i64" |
| 2686 | ); |
| 2687 | } |
| 2688 | }; |
| 2689 | InstructionData::UnaryImm { |
| 2690 | opcode, |
| 2691 | imm: Imm64::new(unsigned), |
| 2692 | } |
| 2693 | } |
| 2694 | InstructionFormat::UnaryIeee16 => InstructionData::UnaryIeee16 { |
| 2695 | opcode, |
| 2696 | imm: self.match_ieee16("expected immediate 16-bit float operand")?, |
| 2697 | }, |
| 2698 | InstructionFormat::UnaryIeee32 => InstructionData::UnaryIeee32 { |
| 2699 | opcode, |
| 2700 | imm: self.match_ieee32("expected immediate 32-bit float operand")?, |
| 2701 | }, |
| 2702 | InstructionFormat::UnaryIeee64 => InstructionData::UnaryIeee64 { |
| 2703 | opcode, |
| 2704 | imm: self.match_ieee64("expected immediate 64-bit float operand")?, |
| 2705 | }, |
| 2706 | InstructionFormat::UnaryConst => { |
| 2707 | let constant_handle = if let Some(Token::Constant(_)) = self.token() { |
| 2708 | // If handed a `const?`, use that. |
| 2709 | let c = self.match_constant()?; |
| 2710 | ctx.check_constant(c, self.loc)?; |
| 2711 | c |
| 2712 | } else if opcode == Opcode::F128const { |
| 2713 | let ieee128 = self.match_ieee128("expected immediate 128-bit float operand")?; |
| 2714 | ctx.function.dfg.constants.insert(ieee128.into()) |
| 2715 | } else if let Some(controlling_type) = explicit_control_type { |
| 2716 | // If an explicit control type is present, we expect a sized value and insert |
| 2717 | // it in the constant pool. |
| 2718 | let uimm128 = self.match_uimm128(controlling_type)?; |
| 2719 | ctx.function.dfg.constants.insert(uimm128) |
| 2720 | } else { |
| 2721 | return err!( |
no test coverage detected