public override IEnumerable<MilocInstruction> Div(DivInstruction s, InstructionStream<MilocInstruction> stream) { var d = constantValue(s, s.RegSource1); if (d.HasValue) { yield return new SraInstruction(s.RegSource0, d.Value, s.RegDest0); } else { yield return s; } }
private Operand MakeVariableAssignment(VariableAssignmentNode node, ILGenerator generator) { SymbolOperand leftHandSide = node.Accessor.Visit(generator) as SymbolOperand; Operand rightHandSide = node.Right.Visit(generator); // If right-hand side exists and has a type, do some type checking /*if (rightHandSide.Type != leftHandSide.Type) * throw new AstWalkerException($"Cannot convert {rightHandSide.Type} to {leftHandSide.Type} ('{leftHandSide.Name}')");*/ if (node.Operator.Type == TokenType.Assignment) { generator.Emmit(new StoreInstruction(leftHandSide, rightHandSide)); return(leftHandSide); } Instruction instr = null; switch (node.Operator.Type) { case TokenType.IncrementAndAssign: instr = new AddInstruction(leftHandSide, leftHandSide, rightHandSide); break; case TokenType.DecrementAndAssign: instr = new SubInstruction(leftHandSide, leftHandSide, rightHandSide); break; case TokenType.MultAndAssign: instr = new MultInstruction(leftHandSide, leftHandSide, rightHandSide); break; case TokenType.DivideAndAssign: instr = new DivInstruction(leftHandSide, leftHandSide, rightHandSide); break; default: throw new InvalidInstructionException($"Unsupported operation: {node.Operator.Value} ({node.Operator.Type})"); } generator.Emmit(instr); return(leftHandSide); }
public void EmitDiv(Type type) { Emit(DivInstruction.Create(type)); }
public Operand Visit(ILGenerator generator, BinaryNode binary) { Operand left = binary.Left.Visit(generator); Operand right = binary.Right.Visit(generator); SymbolOperand tmpname = generator.SymbolTable.NewTempSymbol(OperandType.Auto); Instruction instr = null; switch (binary.Operator.Type) { case TokenType.Addition: instr = new AddInstruction(tmpname, left, right); break; case TokenType.Minus: instr = new SubInstruction(tmpname, left, right); break; case TokenType.Multiplication: instr = new MultInstruction(tmpname, left, right); break; case TokenType.Division: instr = new DivInstruction(tmpname, left, right); break; case TokenType.Or: instr = new OrInstruction(tmpname, left, right); break; case TokenType.And: instr = new AndInstruction(tmpname, left, right); break; case TokenType.GreatThan: instr = new CgtInstruction(tmpname, left, right); break; case TokenType.GreatThanEqual: instr = new CgteInstruction(tmpname, left, right); break; case TokenType.LessThan: instr = new CltInstruction(tmpname, left, right); break; case TokenType.LessThanEqual: instr = new ClteInstruction(tmpname, left, right); break; case TokenType.Equal: case TokenType.NotEqual: // Use NOT instruction instr = new CeqInstruction(tmpname, left, right); break; } generator.Emmit(new VarInstruction(tmpname, null)); generator.Emmit(instr); if (binary.Operator.Type == TokenType.NotEqual) { SymbolOperand notname = generator.SymbolTable.NewTempSymbol(OperandType.Auto); generator.Emmit(new VarInstruction(notname, null)); generator.Emmit(new NotInstruction(notname, tmpname)); return(notname); } return(tmpname); }
private bool GenerateNode(out OneOperandNode node) { node = null; InstructionToken instructionToken; if (this.ExpectInstructionToken(out instructionToken)) { Instructions instruction = instructionToken.Instruction; switch (instruction) { case Instructions.Mov: { Token operand1; Token operand2; if (this.ExpectTwoOperands(out operand1, out operand2)) { node = new MovInstruction(this.rawInput, instructionToken, operand1, operand2); } else { this.LogExpectedTwoOperandsError(instructionToken); return(false); } } break; case Instructions.Add: { Token operand1; Token operand2; if (this.ExpectTwoOperands(out operand1, out operand2)) { node = new AddInstruction(this.rawInput, instructionToken, operand1, operand2); } else { this.LogExpectedTwoOperandsError(instructionToken); return(false); } } break; case Instructions.Sub: { Token operand1; Token operand2; if (this.ExpectTwoOperands(out operand1, out operand2)) { node = new SubInstruction(this.rawInput, instructionToken, operand1, operand2); } else { this.LogExpectedTwoOperandsError(instructionToken); return(false); } } break; case Instructions.Mul: { Token operand1; Token operand2; if (this.ExpectTwoOperands(out operand1, out operand2)) { node = new MulInstruction(this.rawInput, instructionToken, operand1, operand2); } else { this.LogExpectedTwoOperandsError(instructionToken); return(false); } } break; case Instructions.Div: { Token operand1; Token operand2; if (this.ExpectTwoOperands(out operand1, out operand2)) { node = new DivInstruction(this.rawInput, instructionToken, operand1, operand2); } else { this.LogExpectedTwoOperandsError(instructionToken); return(false); } } break; case Instructions.Cmp: { Token operand1; Token operand2; if (this.ExpectTwoOperands(out operand1, out operand2)) { node = new CmpInstruction(this.rawInput, instructionToken, operand1, operand2); } else { this.LogExpectedTwoOperandsError(instructionToken); return(false); } } break; case Instructions.Inc: { Token operand; if (this.ExpectOneOperand(out operand)) { node = new IncInstruction(this.rawInput, instructionToken, operand); } else { this.LogExpectedOneOperandError(instructionToken); return(false); } } break; case Instructions.Dec: { Token operand; if (this.ExpectOneOperand(out operand)) { node = new DecInstruction(this.rawInput, instructionToken, operand); } else { this.LogExpectedOneOperandError(instructionToken); return(false); } } break; case Instructions.Jmp: { Token operand; if (this.ExpectOneOperand(out operand)) { node = new JmpInstruction(this.rawInput, instructionToken, operand); } else { this.LogExpectedOneOperandError(instructionToken); return(false); } } break; case Instructions.Jeq: { Token operand; if (this.ExpectOneOperand(out operand)) { node = new JeqInstruction(this.rawInput, instructionToken, operand); } else { this.LogExpectedOneOperandError(instructionToken); return(false); } } break; case Instructions.Jne: { Token operand; if (this.ExpectOneOperand(out operand)) { node = new JneInstruction(this.rawInput, instructionToken, operand); } else { this.LogExpectedOneOperandError(instructionToken); return(false); } } break; case Instructions.Jsm: { Token operand; if (this.ExpectOneOperand(out operand)) { node = new JsmInstruction(this.rawInput, instructionToken, operand); } else { this.LogExpectedOneOperandError(instructionToken); return(false); } } break; case Instructions.Jns: { Token operand; if (this.ExpectOneOperand(out operand)) { node = new JnsInstruction(this.rawInput, instructionToken, operand); } else { this.LogExpectedOneOperandError(instructionToken); return(false); } } break; } } return(true); }