private bool ParseLabeledInstructionOperand(ParseTreeNode node, Block block, out Instruction.OperandElement res) { List <Label> labelList = new List <Label>(); ParseTreeNode operandNode = node; while (true) { if (operandNode.ChildNodes.Count == 1) { //instrOperand operandNode = operandNode.ChildNodes[0]; break; } else if (operandNode.ChildNodes.Count == 2) { //label + labeledInstrOperands ParseTreeNode lblNode = operandNode.ChildNodes[0]; Label lbl = new Label() { AssemblePosition = new Assemble.AssemblePosition(this.ParsingFilePath, lblNode), Name = lblNode.ChildNodes[0].Token.Text, DefinedBlock = block }; labelList.Add(lbl); operandNode = operandNode.ChildNodes[1]; } } if (!ParseInstructionOperand(operandNode, block, labelList, out res)) { return(false); } return(true); }
protected static bool CheckRegisterOperand(Instruction.OperandElement operand, int rangeMin, int rangeMax) { if (operand.Immediate.Type != ValueBaseType.Register) { return(false); } if (operand.RegisterNo < rangeMin || operand.RegisterNo > rangeMax) { return(false); } return(true); }
protected static bool CheckImmediateOperand(Instruction.OperandElement operand, int rangeMin, int rangeMax) { if (operand.Immediate.Type != ValueBaseType.Immediate) { return(false); } int imm = (int)operand.Immediate.GetValue(BytesPerWord); if (imm < rangeMin || imm > rangeMax) { return(false); } return(true); }
protected static bool ConvertRegisterName(Instruction.OperandElement operand, int operandIndex, List <AssembleError> errorList) { if (operand.Immediate.Type != ValueBaseType.Register) { return(true); } RegisterInfo reginfo = operand.Immediate.GetRegister(); if (!reginfo.IsSpecifiedByName) { operand.RegisterNo = reginfo.No; //Copy return(true); } RegisterMapping.RegisterElement e; if (!SubRiscAssembler.RegisterMapping.SearchByName(reginfo.Name, out e)) { errorList.Add(new Interface.Assemble.AssembleError() { Title = "Assemble", Detail = $"Invalid register name '{e.Name}'", Position = operand.AssemblePosition }); return(false); } if (e.GetRegisterNumber(operandIndex) < 0) { errorList.Add(new Interface.Assemble.AssembleError() { Title = "Assemble", Detail = $"Register ${e.Name} cannot be used for {operandIndex+1}th operand", Position = operand.AssemblePosition }); return(false); } operand.RegisterNo = e.GetRegisterNumber(operandIndex); return(true); }
private bool ParseInstructionOperand(ParseTreeNode node, Block block, List <Label> labels, out Instruction.OperandElement res) { res = new Assemble.Instruction.OperandElement(); res.AssemblePosition = new Assemble.AssemblePosition(this.ParsingFilePath, node); res.Labels = labels; foreach (var e in labels) { e.SetLabelPlacedInfo(res.PlacedInfo); } ParseTreeNode op = node.ChildNodes[0]; if (op.Term.Name == "operand-register") { ValueBase val; if (!ParseRegisterInfo(op, block, out val)) { return(false); } res.Immediate = val; return(true); } else if (op.Term.Name == "operand-reference") { //Recognize as immediate res.Immediate = new ValueReference(op.ChildNodes[0].Token.Text, block); res.Immediate.AssemblePosition = res.AssemblePosition; return(true); } else if (op.Term.Name == "operand-immediate") { ValueBase val; if (!ParseImmediateValue(op.ChildNodes[0], block, out val)) { return(false); } res.Immediate = val; return(true); } ReportError("InstructionOperand", "Unknown instruction operand type.", op); return(false); }