use super::super::MMixAssembler;
use super::super::Rule;
use super::super::expressions::ExprValue;
use super::super::tree::Children;
use super::MMixInstruction;
impl MMixAssembler {
pub(super) fn parse_inst_set(
&self,
pair: pest::iterators::Pair<Rule>,
) -> Result<MMixInstruction, String> {
let mut parts = Children::of(pair);
let _mnem = parts.next(); let operands = parts.required()?; let mut ops = Children::of(operands);
let dest = self.parse_register(ops.required()?)?;
self.lower_set_source(dest, ops.required()?)
}
fn lower_set_source(
&self,
dest: u8,
pair: pest::iterators::Pair<Rule>,
) -> Result<MMixInstruction, String> {
let (line, col) = pair.line_col();
let text = pair.as_str().trim();
match self.eval_expr(pair)? {
ExprValue::Register(r) => {
let reg = self.require_register_in_range(r, line, col)?;
Ok(MMixInstruction::SETRR(dest, reg))
}
ExprValue::Pure(value) => {
if value <= 0xFFFF {
return Ok(MMixInstruction::SETL(dest, value as u16));
}
let hint = if value >= 0x8000_0000_0000_0000 && text.starts_with('-') {
"use SETI or NEG for a negative constant"
} else {
"use SETI for a wider constant"
};
Err(format!(
"{}:{}:{}: immediate operand {} out of range 0..65535 for SET; {}",
self.current_filename,
line,
col,
Self::quote_out_of_range(value, text),
hint
))
}
}
}
pub(super) fn parse_inst_seti(
&self,
pair: pest::iterators::Pair<Rule>,
) -> Result<MMixInstruction, String> {
let mut parts = Children::of(pair);
let _mnem = parts.next(); let operands = parts.required()?; let mut ops = Children::of(operands);
let dest_reg = self.parse_register(ops.required()?)?;
let val = self.parse_number(ops.required()?)?;
Ok(MMixInstruction::SET(dest_reg, val))
}
pub(super) fn parse_inst_setl(
&self,
pair: pest::iterators::Pair<Rule>,
) -> Result<MMixInstruction, String> {
let mut parts = Children::of(pair);
let _mnem = parts.next();
let operands = parts.required()?;
let mut ops = Children::of(operands);
let reg = self.parse_register(ops.required()?)?;
let val = self.imm_wyde(ops.required()?, "SETL")?;
Ok(MMixInstruction::SETL(reg, val))
}
pub(super) fn parse_inst_seth(
&self,
pair: pest::iterators::Pair<Rule>,
) -> Result<MMixInstruction, String> {
let mut parts = Children::of(pair);
let _mnem = parts.next();
let operands = parts.required()?;
let mut ops = Children::of(operands);
let reg = self.parse_register(ops.required()?)?;
let val = self.imm_wyde(ops.required()?, "SETH")?;
Ok(MMixInstruction::SETH(reg, val))
}
pub(super) fn parse_inst_setmh(
&self,
pair: pest::iterators::Pair<Rule>,
) -> Result<MMixInstruction, String> {
let mut parts = Children::of(pair);
let _mnem = parts.next();
let operands = parts.required()?;
let mut ops = Children::of(operands);
let reg = self.parse_register(ops.required()?)?;
let val = self.imm_wyde(ops.required()?, "SETMH")?;
Ok(MMixInstruction::SETMH(reg, val))
}
pub(super) fn parse_inst_setml(
&self,
pair: pest::iterators::Pair<Rule>,
) -> Result<MMixInstruction, String> {
let mut parts = Children::of(pair);
let _mnem = parts.next();
let operands = parts.required()?;
let mut ops = Children::of(operands);
let reg = self.parse_register(ops.required()?)?;
let val = self.imm_wyde(ops.required()?, "SETML")?;
Ok(MMixInstruction::SETML(reg, val))
}
pub(super) fn parse_inst_incl(
&self,
pair: pest::iterators::Pair<Rule>,
) -> Result<MMixInstruction, String> {
let mut parts = Children::of(pair);
let _mnem = parts.next();
let operands = parts.required()?;
let mut ops = Children::of(operands);
let reg = self.parse_register(ops.required()?)?;
let val = self.imm_wyde(ops.required()?, "INCL")?;
Ok(MMixInstruction::INCL(reg, val))
}
pub(super) fn parse_inst_inch(
&self,
pair: pest::iterators::Pair<Rule>,
) -> Result<MMixInstruction, String> {
let mut parts = Children::of(pair);
let _mnem = parts.next();
let operands = parts.required()?;
let mut ops = Children::of(operands);
let reg = self.parse_register(ops.required()?)?;
let val = self.imm_wyde(ops.required()?, "INCH")?;
Ok(MMixInstruction::INCH(reg, val))
}
pub(super) fn parse_inst_incmh(
&self,
pair: pest::iterators::Pair<Rule>,
) -> Result<MMixInstruction, String> {
let mut parts = Children::of(pair);
let _mnem = parts.next();
let operands = parts.required()?;
let mut ops = Children::of(operands);
let reg = self.parse_register(ops.required()?)?;
let val = self.imm_wyde(ops.required()?, "INCMH")?;
Ok(MMixInstruction::INCMH(reg, val))
}
pub(super) fn parse_inst_incml(
&self,
pair: pest::iterators::Pair<Rule>,
) -> Result<MMixInstruction, String> {
let mut parts = Children::of(pair);
let _mnem = parts.next();
let operands = parts.required()?;
let mut ops = Children::of(operands);
let reg = self.parse_register(ops.required()?)?;
let val = self.imm_wyde(ops.required()?, "INCML")?;
Ok(MMixInstruction::INCML(reg, val))
}
pub(super) fn parse_inst_orh(
&self,
pair: pest::iterators::Pair<Rule>,
) -> Result<MMixInstruction, String> {
let mut parts = Children::of(pair);
let _mnem = parts.next();
let operands = parts.required()?;
let mut ops = Children::of(operands);
let reg = self.parse_register(ops.required()?)?;
let val = self.imm_wyde(ops.required()?, "ORH")?;
Ok(MMixInstruction::ORH(reg, val))
}
pub(super) fn parse_inst_ormh(
&self,
pair: pest::iterators::Pair<Rule>,
) -> Result<MMixInstruction, String> {
let mut parts = Children::of(pair);
let _mnem = parts.next();
let operands = parts.required()?;
let mut ops = Children::of(operands);
let reg = self.parse_register(ops.required()?)?;
let val = self.imm_wyde(ops.required()?, "ORMH")?;
Ok(MMixInstruction::ORMH(reg, val))
}
pub(super) fn parse_inst_orml(
&self,
pair: pest::iterators::Pair<Rule>,
) -> Result<MMixInstruction, String> {
let mut parts = Children::of(pair);
let _mnem = parts.next();
let operands = parts.required()?;
let mut ops = Children::of(operands);
let reg = self.parse_register(ops.required()?)?;
let val = self.imm_wyde(ops.required()?, "ORML")?;
Ok(MMixInstruction::ORML(reg, val))
}
pub(super) fn parse_inst_orl(
&self,
pair: pest::iterators::Pair<Rule>,
) -> Result<MMixInstruction, String> {
let mut parts = Children::of(pair);
let _mnem = parts.next();
let operands = parts.required()?;
let mut ops = Children::of(operands);
let reg = self.parse_register(ops.required()?)?;
let val = self.imm_wyde(ops.required()?, "ORL")?;
Ok(MMixInstruction::ORL(reg, val))
}
pub(super) fn parse_inst_andnh(
&self,
pair: pest::iterators::Pair<Rule>,
) -> Result<MMixInstruction, String> {
let mut parts = Children::of(pair);
let _mnem = parts.next();
let operands = parts.required()?;
let mut ops = Children::of(operands);
let reg = self.parse_register(ops.required()?)?;
let val = self.imm_wyde(ops.required()?, "ANDNH")?;
Ok(MMixInstruction::ANDNH(reg, val))
}
pub(super) fn parse_inst_andnmh(
&self,
pair: pest::iterators::Pair<Rule>,
) -> Result<MMixInstruction, String> {
let mut parts = Children::of(pair);
let _mnem = parts.next();
let operands = parts.required()?;
let mut ops = Children::of(operands);
let reg = self.parse_register(ops.required()?)?;
let val = self.imm_wyde(ops.required()?, "ANDNMH")?;
Ok(MMixInstruction::ANDNMH(reg, val))
}
pub(super) fn parse_inst_andnml(
&self,
pair: pest::iterators::Pair<Rule>,
) -> Result<MMixInstruction, String> {
let mut parts = Children::of(pair);
let _mnem = parts.next();
let operands = parts.required()?;
let mut ops = Children::of(operands);
let reg = self.parse_register(ops.required()?)?;
let val = self.imm_wyde(ops.required()?, "ANDNML")?;
Ok(MMixInstruction::ANDNML(reg, val))
}
pub(super) fn parse_inst_andnl(
&self,
pair: pest::iterators::Pair<Rule>,
) -> Result<MMixInstruction, String> {
let mut parts = Children::of(pair);
let _mnem = parts.next();
let operands = parts.required()?;
let mut ops = Children::of(operands);
let reg = self.parse_register(ops.required()?)?;
let val = self.imm_wyde(ops.required()?, "ANDNL")?;
Ok(MMixInstruction::ANDNL(reg, val))
}
}