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; }
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; }
public ParsedOperand(MachineOperand op, Symbol sym) { this.op = op; this.sym = sym; }
public ParsedOperand(MachineOperand op) { this.op = op; this.sym = null; }
private void ReferToSymbol(Symbol psym, int off, DataType width) { if (psym.fResolved) { emitter.PatchLe(off, psym.offset, width); } else { psym.AddForwardReference(off, width, 1); } }
public ParsedOperand(MachineOperand op, Symbol sym, bool longJmp) { this.op = op; this.sym = sym; this.longJmp = longJmp; }
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"); } }
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); } }
public AssembledSegment(IEmitter emitter, Symbol sym) { this.Emitter = emitter; this.Symbol = sym; this.Relocations = new List<Relocation>(); }
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; }
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. }
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); }
private void ResolveSegmentForwardReferences(Symbol sym) { AssembledSegment tempSeg; if (symbolSegments.TryGetValue(sym, out tempSeg)) { currentSegment.Relocations.AddRange(tempSeg.Relocations); } }