Esempio n. 1
0
		public Symbol CreateSymbol(string s)
		{
			Symbol sym;
            if (!symbols.TryGetValue(s, out sym))
			{
				// Forward reference to a symbol. 
				sym = new Symbol(s);
				symbols.Add(s, sym);
			}
			return sym;
		}
Esempio n. 2
0
		public Symbol DefineSymbol(string s, int off)
		{
			Symbol	sym;
			if (symbols.ContainsKey(s))
			{
				sym = symbols[s];
				if (sym.fResolved || sym.offset != 0)
					throw new ApplicationException("symbol '" + s + "' redefined");
			}
			else
			{
				sym = new Symbol(s);
				symbols[s] = sym;
			}
			sym.fResolved = true;
			sym.offset = off;
			return sym;
		}
Esempio n. 3
0
		public ParsedOperand(MachineOperand op, Symbol sym)
		{
			this.op = op;
			this.sym = sym;
		}
Esempio n. 4
0
		public ParsedOperand(MachineOperand op)
		{
			this.op = op;
			this.sym = null;
		}
Esempio n. 5
0
 private void ReferToSymbol(Symbol psym, int off, DataType width)
 {
     if (psym.fResolved)
     {
         emitter.PatchLe(off, psym.offset, width);
     }
     else
     {
         psym.AddForwardReference(off, width, 1);
     }
 }
Esempio n. 6
0
		public ParsedOperand(MachineOperand op, Symbol sym, bool longJmp)
		{
			this.op = op;
			this.sym = sym;
			this.longJmp = longJmp;
		}
Esempio n. 7
0
		private void ParseMemoryFactor(MemoryOperand memOp)
		{
			Token token = lexer.GetToken();
			RegisterStorage reg = RegisterStorage.None;
			switch (token)
			{
			default:
				OnError("unexpected token: " + token);
				return;
			case Token.INTEGER:
				totalInt += lexer.Integer;
				break;
			case Token.REGISTER:
			{
				reg = lexer.Register;
 				PrimitiveType width = reg.DataType;
 				if (addrWidth == null)
 					addrWidth = width;
 				else if (addrWidth != width)
 					throw new ApplicationException("Conflicting address widths");
 				break;
			}
			case Token.ID:
			{
				int v;
                if (symtab.Equates.TryGetValue(lexer.StringLiteral.ToLower(), out v))
				{
                    totalInt += v;
				}
				else
				{
					sym = symtab.CreateSymbol(lexer.StringLiteral);
					totalInt += unchecked((int) addrBase.Offset);
				}
				break;
			}
			}

			if (lexer.PeekToken() == Token.TIMES)
			{
				if (reg == RegisterStorage.None)
					throw new ApplicationException("Scale factor must be preceded by a register");
				lexer.GetToken();
				if (memOp.Index != RegisterStorage.None)
					throw new ApplicationException("Scale can only be used once in an addressing form");
				Expect(Token.INTEGER, "Expected an integer scale");
				if (lexer.Integer != 1 && lexer.Integer != 2 && lexer.Integer != 4 && lexer.Integer != 8)
					throw new ApplicationException("Only scales 1, 2, 4, and 8 are supported");
				memOp.Scale = (byte) lexer.Integer;
				memOp.Index = reg;
			}
			else if (reg != RegisterStorage.None)
			{
				if (memOp.Base == RegisterStorage.None)
					memOp.Base = reg;
				else if (memOp.Index == RegisterStorage.None)
				{
					memOp.Index = reg;
					memOp.Scale = 1;
				}
				else
					throw new ApplicationException("Can't have more than two registers in an addressing form");
			}
		}
Esempio n. 8
0
		public ParsedOperand ParseOperand()
		{
			sym = null;
			totalInt = 0;
			segOverride = RegisterStorage.None;
			Token token = lexer.GetToken();
			switch (token)
			{
			default:
				OnError(string.Format("Unexpected token '{0}'", token));
				return null;
			case Token.BRA:
				return ParseMemoryOperand(RegisterStorage.None);
			case Token.MINUS:
				Expect( Token.INTEGER );
				totalInt -= lexer.Integer;
				return IntegerCommon();
			case Token.INTEGER:
				totalInt += lexer.Integer;
				return IntegerCommon();
			case Token.REGISTER:
			{
				RegisterStorage reg = lexer.Register;
				switch (lexer.PeekToken())
				{
				case Token.COLON:		// Segment override of the form "es:" usually precedes a memory operand.
					if (!(reg is SegmentRegister))
						throw new ApplicationException(reg.ToString() + " is not a segment register.");
					Expect(Token.COLON);			// Discard ':'
					Expect(Token.BRA);
					return ParseMemoryOperand(reg);
				default:
					return new ParsedOperand(new RegisterOperand(reg));
				}
			}
			case Token.OFFSET:
				Expect(Token.ID);
				return new ParsedOperand(
					new ImmediateOperand(Constant.Create(defaultWordWidth, addrBase.Offset)),
					symtab.CreateSymbol(lexer.StringLiteral));
				
			case Token.ID:
			{
                int v;
                if (symtab.Equates.TryGetValue(lexer.StringLiteral.ToLower(), out v))
                {
					totalInt += lexer.Integer;
					return IntegerCommon();
				}
				return new ParsedOperand(
							   new MemoryOperand(addrWidth, Constant.Create(defaultWordWidth, addrBase.Offset)),
							   symtab.CreateSymbol(lexer.StringLiteral));
			}
			case Token.WORD:
				return ParsePtrOperand(PrimitiveType.Word16);
			case Token.BYTE:
				return ParsePtrOperand(PrimitiveType.Byte);
			case Token.DWORD:
				return ParsePtrOperand(PrimitiveType.Word32);
			case Token.QWORD:
				return ParsePtrOperand(PrimitiveType.Word64);
			case Token.ST:
				return new ParsedOperand(ParseFpuOperand(), null);
			}
		}
Esempio n. 9
0
 public AssembledSegment(IEmitter emitter, Symbol sym)
 {
     this.Emitter = emitter;
     this.Symbol = sym;
     this.Relocations = new List<Relocation>();
 }
Esempio n. 10
0
 private AssembledSegment GetSymbolSegmentReference(Symbol sym)
 {
     AssembledSegment seg;
     if (symbolSegments.TryGetValue(sym, out seg))
         return seg;
     seg = new AssembledSegment(emitter, null);
     symbolSegments.Add(sym, seg);
     return seg;
 }
Esempio n. 11
0
 private void EmitReferenceToSymbolSegment(Symbol sym)
 {
     var seg = GetSymbolSegmentReference(sym);
     seg.Relocations.Add(new AssembledSegment.Relocation { Segment=currentSegment, Offset=(uint) emitter.Length });
     emitter.EmitLeUInt16(0);            // make space for the segment selector, will be overwritten at relocation time.
 }
Esempio n. 12
0
 internal void EmitModRM(int reg, MemoryOperand memOp, byte b, Symbol sym)
 {
     Constant offset = modRm.EmitModRMPrefix(reg, memOp);
     emitter.EmitByte(b);
     int offsetPosition = emitter.Position;
     EmitOffset(offset);
     if (sym != null)
         ReferToSymbol(sym, emitter.Position, offset.DataType);
 }
Esempio n. 13
0
 private void ResolveSegmentForwardReferences(Symbol sym)
 {
     AssembledSegment tempSeg;
     if (symbolSegments.TryGetValue(sym, out tempSeg))
     {
         currentSegment.Relocations.AddRange(tempSeg.Relocations);
     }
 }