diff options
Diffstat (limited to 'tools/llvm-mc')
-rw-r--r-- | tools/llvm-mc/AsmExpr.cpp | 162 | ||||
-rw-r--r-- | tools/llvm-mc/AsmExpr.h | 179 | ||||
-rw-r--r-- | tools/llvm-mc/MC-X86Specific.cpp | 266 |
3 files changed, 0 insertions, 607 deletions
diff --git a/tools/llvm-mc/AsmExpr.cpp b/tools/llvm-mc/AsmExpr.cpp deleted file mode 100644 index c3362e4..0000000 --- a/tools/llvm-mc/AsmExpr.cpp +++ /dev/null @@ -1,162 +0,0 @@ -//===- AsmExpr.cpp - Assembly file expressions ----------------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "AsmExpr.h" -#include "llvm/MC/MCContext.h" -#include "llvm/MC/MCSymbol.h" -#include "llvm/MC/MCValue.h" -using namespace llvm; - -AsmExpr::~AsmExpr() { -} - -bool AsmExpr::EvaluateAsAbsolute(MCContext &Ctx, int64_t &Res) const { - MCValue Value; - - if (!EvaluateAsRelocatable(Ctx, Value) || !Value.isAbsolute()) - return false; - - Res = Value.getConstant(); - return true; -} - -static bool EvaluateSymbolicAdd(const MCValue &LHS, MCSymbol *RHS_A, - MCSymbol *RHS_B, int64_t RHS_Cst, - MCValue &Res) { - // We can't add or subtract two symbols. - if ((LHS.getSymA() && RHS_A) || - (LHS.getSymB() && RHS_B)) - return false; - - MCSymbol *A = LHS.getSymA() ? LHS.getSymA() : RHS_A; - MCSymbol *B = LHS.getSymB() ? LHS.getSymB() : RHS_B; - if (B) { - // If we have a negated symbol, then we must have also have a non-negated - // symbol in order to encode the expression. We can do this check later to - // permit expressions which eventually fold to a representable form -- such - // as (a + (0 - b)) -- if necessary. - if (!A) - return false; - } - Res = MCValue::get(A, B, LHS.getConstant() + RHS_Cst); - return true; -} - -bool AsmExpr::EvaluateAsRelocatable(MCContext &Ctx, MCValue &Res) const { - switch (getKind()) { - default: - assert(0 && "Invalid assembly expression kind!"); - - case Constant: - Res = MCValue::get(cast<AsmConstantExpr>(this)->getValue()); - return true; - - case SymbolRef: { - MCSymbol *Sym = cast<AsmSymbolRefExpr>(this)->getSymbol(); - if (const MCValue *Value = Ctx.GetSymbolValue(Sym)) - Res = *Value; - else - Res = MCValue::get(Sym, 0, 0); - return true; - } - - case Unary: { - const AsmUnaryExpr *AUE = cast<AsmUnaryExpr>(this); - MCValue Value; - - if (!AUE->getSubExpr()->EvaluateAsRelocatable(Ctx, Value)) - return false; - - switch (AUE->getOpcode()) { - case AsmUnaryExpr::LNot: - if (!Value.isAbsolute()) - return false; - Res = MCValue::get(!Value.getConstant()); - break; - case AsmUnaryExpr::Minus: - /// -(a - b + const) ==> (b - a - const) - if (Value.getSymA() && !Value.getSymA()) - return false; - Res = MCValue::get(Value.getSymB(), Value.getSymA(), - -Value.getConstant()); - break; - case AsmUnaryExpr::Not: - if (!Value.isAbsolute()) - return false; - Res = MCValue::get(~Value.getConstant()); - break; - case AsmUnaryExpr::Plus: - Res = Value; - break; - } - - return true; - } - - case Binary: { - const AsmBinaryExpr *ABE = cast<AsmBinaryExpr>(this); - MCValue LHSValue, RHSValue; - - if (!ABE->getLHS()->EvaluateAsRelocatable(Ctx, LHSValue) || - !ABE->getRHS()->EvaluateAsRelocatable(Ctx, RHSValue)) - return false; - - // We only support a few operations on non-constant expressions, handle - // those first. - if (!LHSValue.isAbsolute() || !RHSValue.isAbsolute()) { - switch (ABE->getOpcode()) { - default: - return false; - case AsmBinaryExpr::Sub: - // Negate RHS and add. - return EvaluateSymbolicAdd(LHSValue, - RHSValue.getSymB(), RHSValue.getSymA(), - -RHSValue.getConstant(), - Res); - - case AsmBinaryExpr::Add: - return EvaluateSymbolicAdd(LHSValue, - RHSValue.getSymA(), RHSValue.getSymB(), - RHSValue.getConstant(), - Res); - } - } - - // FIXME: We need target hooks for the evaluation. It may be limited in - // width, and gas defines the result of comparisons differently from Apple - // as (the result is sign extended). - int64_t LHS = LHSValue.getConstant(), RHS = RHSValue.getConstant(); - int64_t Result = 0; - switch (ABE->getOpcode()) { - case AsmBinaryExpr::Add: Result = LHS + RHS; break; - case AsmBinaryExpr::And: Result = LHS & RHS; break; - case AsmBinaryExpr::Div: Result = LHS / RHS; break; - case AsmBinaryExpr::EQ: Result = LHS == RHS; break; - case AsmBinaryExpr::GT: Result = LHS > RHS; break; - case AsmBinaryExpr::GTE: Result = LHS >= RHS; break; - case AsmBinaryExpr::LAnd: Result = LHS && RHS; break; - case AsmBinaryExpr::LOr: Result = LHS || RHS; break; - case AsmBinaryExpr::LT: Result = LHS < RHS; break; - case AsmBinaryExpr::LTE: Result = LHS <= RHS; break; - case AsmBinaryExpr::Mod: Result = LHS % RHS; break; - case AsmBinaryExpr::Mul: Result = LHS * RHS; break; - case AsmBinaryExpr::NE: Result = LHS != RHS; break; - case AsmBinaryExpr::Or: Result = LHS | RHS; break; - case AsmBinaryExpr::Shl: Result = LHS << RHS; break; - case AsmBinaryExpr::Shr: Result = LHS >> RHS; break; - case AsmBinaryExpr::Sub: Result = LHS - RHS; break; - case AsmBinaryExpr::Xor: Result = LHS ^ RHS; break; - } - - Res = MCValue::get(Result); - return true; - } - } -} - diff --git a/tools/llvm-mc/AsmExpr.h b/tools/llvm-mc/AsmExpr.h deleted file mode 100644 index 84e58ff..0000000 --- a/tools/llvm-mc/AsmExpr.h +++ /dev/null @@ -1,179 +0,0 @@ -//===- AsmExpr.h - Assembly file expressions --------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef ASMEXPR_H -#define ASMEXPR_H - -#include "llvm/Support/Casting.h" -#include "llvm/Support/DataTypes.h" - -namespace llvm { -class MCContext; -class MCSymbol; -class MCValue; - -/// AsmExpr - Base class for the full range of assembler expressions which are -/// needed for parsing. -class AsmExpr { -public: - enum AsmExprKind { - Binary, ///< Binary expressions. - Constant, ///< Constant expressions. - SymbolRef, ///< References to labels and assigned expressions. - Unary ///< Unary expressions. - }; - -private: - AsmExprKind Kind; - -protected: - AsmExpr(AsmExprKind _Kind) : Kind(_Kind) {} - -public: - virtual ~AsmExpr(); - - AsmExprKind getKind() const { return Kind; } - - /// EvaluateAsAbsolute - Try to evaluate the expression to an absolute value. - /// - /// @param Res - The absolute value, if evaluation succeeds. - /// @result - True on success. - bool EvaluateAsAbsolute(MCContext &Ctx, int64_t &Res) const; - - /// EvaluateAsRelocatable - Try to evaluate the expression to a relocatable - /// value, i.e. an expression of the fixed form (a - b + constant). - /// - /// @param Res - The relocatable value, if evaluation succeeds. - /// @result - True on success. - bool EvaluateAsRelocatable(MCContext &Ctx, MCValue &Res) const; - - static bool classof(const AsmExpr *) { return true; } -}; - -//// AsmConstantExpr - Represent a constant integer expression. -class AsmConstantExpr : public AsmExpr { - int64_t Value; - -public: - AsmConstantExpr(int64_t _Value) - : AsmExpr(AsmExpr::Constant), Value(_Value) {} - - int64_t getValue() const { return Value; } - - static bool classof(const AsmExpr *E) { - return E->getKind() == AsmExpr::Constant; - } - static bool classof(const AsmConstantExpr *) { return true; } -}; - -/// AsmSymbolRefExpr - Represent a reference to a symbol from inside an -/// expression. -/// -/// A symbol reference in an expression may be a use of a label, a use of an -/// assembler variable (defined constant), or constitute an implicit definition -/// of the symbol as external. -class AsmSymbolRefExpr : public AsmExpr { - MCSymbol *Symbol; - -public: - AsmSymbolRefExpr(MCSymbol *_Symbol) - : AsmExpr(AsmExpr::SymbolRef), Symbol(_Symbol) {} - - MCSymbol *getSymbol() const { return Symbol; } - - static bool classof(const AsmExpr *E) { - return E->getKind() == AsmExpr::SymbolRef; - } - static bool classof(const AsmSymbolRefExpr *) { return true; } -}; - -/// AsmUnaryExpr - Unary assembler expressions. -class AsmUnaryExpr : public AsmExpr { -public: - enum Opcode { - LNot, ///< Logical negation. - Minus, ///< Unary minus. - Not, ///< Bitwise negation. - Plus ///< Unary plus. - }; - -private: - Opcode Op; - AsmExpr *Expr; - -public: - AsmUnaryExpr(Opcode _Op, AsmExpr *_Expr) - : AsmExpr(AsmExpr::Unary), Op(_Op), Expr(_Expr) {} - ~AsmUnaryExpr() { - delete Expr; - } - - Opcode getOpcode() const { return Op; } - - AsmExpr *getSubExpr() const { return Expr; } - - static bool classof(const AsmExpr *E) { - return E->getKind() == AsmExpr::Unary; - } - static bool classof(const AsmUnaryExpr *) { return true; } -}; - -/// AsmBinaryExpr - Binary assembler expressions. -class AsmBinaryExpr : public AsmExpr { -public: - enum Opcode { - Add, ///< Addition. - And, ///< Bitwise and. - Div, ///< Division. - EQ, ///< Equality comparison. - GT, ///< Greater than comparison. - GTE, ///< Greater than or equal comparison. - LAnd, ///< Logical and. - LOr, ///< Logical or. - LT, ///< Less than comparison. - LTE, ///< Less than or equal comparison. - Mod, ///< Modulus. - Mul, ///< Multiplication. - NE, ///< Inequality comparison. - Or, ///< Bitwise or. - Shl, ///< Bitwise shift left. - Shr, ///< Bitwise shift right. - Sub, ///< Subtraction. - Xor ///< Bitwise exclusive or. - }; - -private: - Opcode Op; - AsmExpr *LHS, *RHS; - -public: - AsmBinaryExpr(Opcode _Op, AsmExpr *_LHS, AsmExpr *_RHS) - : AsmExpr(AsmExpr::Binary), Op(_Op), LHS(_LHS), RHS(_RHS) {} - ~AsmBinaryExpr() { - delete LHS; - delete RHS; - } - - Opcode getOpcode() const { return Op; } - - /// getLHS - Get the left-hand side expression of the binary operator. - AsmExpr *getLHS() const { return LHS; } - - /// getRHS - Get the right-hand side expression of the binary operator. - AsmExpr *getRHS() const { return RHS; } - - static bool classof(const AsmExpr *E) { - return E->getKind() == AsmExpr::Binary; - } - static bool classof(const AsmBinaryExpr *) { return true; } -}; - -} // end namespace llvm - -#endif diff --git a/tools/llvm-mc/MC-X86Specific.cpp b/tools/llvm-mc/MC-X86Specific.cpp deleted file mode 100644 index fec13ce..0000000 --- a/tools/llvm-mc/MC-X86Specific.cpp +++ /dev/null @@ -1,266 +0,0 @@ -//===- MC-X86Specific.cpp - X86-Specific code for MC ----------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file implements X86-specific parsing, encoding and decoding stuff for -// MC. -// -//===----------------------------------------------------------------------===// - -#include "AsmParser.h" -#include "llvm/MC/MCInst.h" -#include "llvm/Support/SourceMgr.h" -using namespace llvm; - -/// X86Operand - Instances of this class represent one X86 machine instruction. -struct AsmParser::X86Operand { - enum { - Register, - Immediate, - Memory - } Kind; - - union { - struct { - unsigned RegNo; - } Reg; - - struct { - MCValue Val; - } Imm; - - struct { - unsigned SegReg; - MCValue Disp; - unsigned BaseReg; - unsigned IndexReg; - unsigned Scale; - } Mem; - }; - - unsigned getReg() const { - assert(Kind == Register && "Invalid access!"); - return Reg.RegNo; - } - - static X86Operand CreateReg(unsigned RegNo) { - X86Operand Res; - Res.Kind = Register; - Res.Reg.RegNo = RegNo; - return Res; - } - static X86Operand CreateImm(MCValue Val) { - X86Operand Res; - Res.Kind = Immediate; - Res.Imm.Val = Val; - return Res; - } - static X86Operand CreateMem(unsigned SegReg, MCValue Disp, unsigned BaseReg, - unsigned IndexReg, unsigned Scale) { - // If there is no index register, we should never have a scale, and we - // should always have a scale (in {1,2,4,8}) if we do. - assert(((Scale == 0 && !IndexReg) || - (IndexReg && (Scale == 1 || Scale == 2 || - Scale == 4 || Scale == 8))) && - "Invalid scale!"); - X86Operand Res; - Res.Kind = Memory; - Res.Mem.SegReg = SegReg; - Res.Mem.Disp = Disp; - Res.Mem.BaseReg = BaseReg; - Res.Mem.IndexReg = IndexReg; - Res.Mem.Scale = Scale; - return Res; - } -}; - -bool AsmParser::ParseX86Register(X86Operand &Op) { - assert(Lexer.getKind() == asmtok::Register && "Invalid token kind!"); - - // FIXME: Decode register number. - Op = X86Operand::CreateReg(123); - Lexer.Lex(); // Eat register token. - - return false; -} - -bool AsmParser::ParseX86Operand(X86Operand &Op) { - switch (Lexer.getKind()) { - default: - return ParseX86MemOperand(Op); - case asmtok::Register: - // FIXME: if a segment register, this could either be just the seg reg, or - // the start of a memory operand. - return ParseX86Register(Op); - case asmtok::Dollar: { - // $42 -> immediate. - Lexer.Lex(); - MCValue Val; - if (ParseRelocatableExpression(Val)) - return true; - Op = X86Operand::CreateImm(Val); - return false; - } - case asmtok::Star: { - Lexer.Lex(); // Eat the star. - - if (Lexer.is(asmtok::Register)) { - if (ParseX86Register(Op)) - return true; - } else if (ParseX86MemOperand(Op)) - return true; - - // FIXME: Note the '*' in the operand for use by the matcher. - return false; - } - } -} - -/// ParseX86MemOperand: segment: disp(basereg, indexreg, scale) -bool AsmParser::ParseX86MemOperand(X86Operand &Op) { - // FIXME: If SegReg ':' (e.g. %gs:), eat and remember. - unsigned SegReg = 0; - - // We have to disambiguate a parenthesized expression "(4+5)" from the start - // of a memory operand with a missing displacement "(%ebx)" or "(,%eax)". The - // only way to do this without lookahead is to eat the ( and see what is after - // it. - MCValue Disp = MCValue::get(0, 0, 0); - if (Lexer.isNot(asmtok::LParen)) { - if (ParseRelocatableExpression(Disp)) return true; - - // After parsing the base expression we could either have a parenthesized - // memory address or not. If not, return now. If so, eat the (. - if (Lexer.isNot(asmtok::LParen)) { - Op = X86Operand::CreateMem(SegReg, Disp, 0, 0, 0); - return false; - } - - // Eat the '('. - Lexer.Lex(); - } else { - // Okay, we have a '('. We don't know if this is an expression or not, but - // so we have to eat the ( to see beyond it. - Lexer.Lex(); // Eat the '('. - - if (Lexer.is(asmtok::Register) || Lexer.is(asmtok::Comma)) { - // Nothing to do here, fall into the code below with the '(' part of the - // memory operand consumed. - } else { - // It must be an parenthesized expression, parse it now. - if (ParseParenRelocatableExpression(Disp)) - return true; - - // After parsing the base expression we could either have a parenthesized - // memory address or not. If not, return now. If so, eat the (. - if (Lexer.isNot(asmtok::LParen)) { - Op = X86Operand::CreateMem(SegReg, Disp, 0, 0, 0); - return false; - } - - // Eat the '('. - Lexer.Lex(); - } - } - - // If we reached here, then we just ate the ( of the memory operand. Process - // the rest of the memory operand. - unsigned BaseReg = 0, IndexReg = 0, Scale = 0; - - if (Lexer.is(asmtok::Register)) { - if (ParseX86Register(Op)) - return true; - BaseReg = Op.getReg(); - } - - if (Lexer.is(asmtok::Comma)) { - Lexer.Lex(); // Eat the comma. - - // Following the comma we should have either an index register, or a scale - // value. We don't support the later form, but we want to parse it - // correctly. - // - // Not that even though it would be completely consistent to support syntax - // like "1(%eax,,1)", the assembler doesn't. - if (Lexer.is(asmtok::Register)) { - if (ParseX86Register(Op)) - return true; - IndexReg = Op.getReg(); - Scale = 1; // If not specified, the scale defaults to 1. - - if (Lexer.isNot(asmtok::RParen)) { - // Parse the scale amount: - // ::= ',' [scale-expression] - if (Lexer.isNot(asmtok::Comma)) - return true; - Lexer.Lex(); // Eat the comma. - - if (Lexer.isNot(asmtok::RParen)) { - int64_t ScaleVal; - if (ParseAbsoluteExpression(ScaleVal)) - return true; - - // Validate the scale amount. - if (ScaleVal != 1 && ScaleVal != 2 && ScaleVal != 4 && ScaleVal != 8) - return TokError("scale factor in address must be 1, 2, 4 or 8"); - Scale = (unsigned)ScaleVal; - } - } - } else if (Lexer.isNot(asmtok::RParen)) { - // Otherwise we have the unsupported form of a scale amount without an - // index. - SMLoc Loc = Lexer.getLoc(); - - int64_t Value; - if (ParseAbsoluteExpression(Value)) - return true; - - return Error(Loc, "cannot have scale factor without index register"); - } - } - - // Ok, we've eaten the memory operand, verify we have a ')' and eat it too. - if (Lexer.isNot(asmtok::RParen)) - return TokError("unexpected token in memory operand"); - Lexer.Lex(); // Eat the ')'. - - Op = X86Operand::CreateMem(SegReg, Disp, BaseReg, IndexReg, Scale); - return false; -} - -/// MatchX86Inst - Convert a parsed instruction name and operand list into a -/// concrete instruction. -static bool MatchX86Inst(const char *Name, - llvm::SmallVector<AsmParser::X86Operand, 3> &Operands, - MCInst &Inst) { - return false; -} - -/// ParseX86InstOperands - Parse the operands of an X86 instruction and return -/// them as the operands of an MCInst. -bool AsmParser::ParseX86InstOperands(const char *InstName, MCInst &Inst) { - llvm::SmallVector<X86Operand, 3> Operands; - - if (Lexer.isNot(asmtok::EndOfStatement)) { - // Read the first operand. - Operands.push_back(X86Operand()); - if (ParseX86Operand(Operands.back())) - return true; - - while (Lexer.is(asmtok::Comma)) { - Lexer.Lex(); // Eat the comma. - - // Parse and remember the operand. - Operands.push_back(X86Operand()); - if (ParseX86Operand(Operands.back())) - return true; - } - } - - return MatchX86Inst(InstName, Operands, Inst); -} |