mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-06-26 23:24:34 +00:00
start straightening out libedis's dependencies and make it fit
better in the llvm world. Among other things, this changes: 1. The guts of libedis are now moved into lib/MC/MCDisassembler 2. llvm-mc now depends on lib/MC/MCDisassembler, not tools/edis, so edis and mc don't have to be built in series. 3. lib/MC/MCDisassembler no longer depends on the C api, the C API depends on it. 4. Various code cleanup changes. There is still a lot to be done to make edis fit with the llvm design, but this is an incremental step in the right direction. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@108869 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
206
lib/MC/MCDisassembler/EDToken.cpp
Normal file
206
lib/MC/MCDisassembler/EDToken.cpp
Normal file
@ -0,0 +1,206 @@
|
||||
//===-- EDToken.cpp - LLVM Enhanced Disassembler --------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file implements the Enhanced Disassembler library's token class. The
|
||||
// token is responsible for vending information about the token, such as its
|
||||
// type and logical value.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "EDToken.h"
|
||||
#include "EDDisassembler.h"
|
||||
#include "llvm/MC/MCParser/MCAsmLexer.h"
|
||||
#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
using namespace llvm;
|
||||
|
||||
EDToken::EDToken(StringRef str,
|
||||
enum tokenType type,
|
||||
uint64_t localType,
|
||||
EDDisassembler &disassembler) :
|
||||
Disassembler(disassembler),
|
||||
Str(str),
|
||||
Type(type),
|
||||
LocalType(localType),
|
||||
OperandID(-1) {
|
||||
}
|
||||
|
||||
EDToken::~EDToken() {
|
||||
}
|
||||
|
||||
void EDToken::makeLiteral(bool sign, uint64_t absoluteValue) {
|
||||
Type = kTokenLiteral;
|
||||
LiteralSign = sign;
|
||||
LiteralAbsoluteValue = absoluteValue;
|
||||
}
|
||||
|
||||
void EDToken::makeRegister(unsigned registerID) {
|
||||
Type = kTokenRegister;
|
||||
RegisterID = registerID;
|
||||
}
|
||||
|
||||
void EDToken::setOperandID(int operandID) {
|
||||
OperandID = operandID;
|
||||
}
|
||||
|
||||
enum EDToken::tokenType EDToken::type() const {
|
||||
return Type;
|
||||
}
|
||||
|
||||
uint64_t EDToken::localType() const {
|
||||
return LocalType;
|
||||
}
|
||||
|
||||
StringRef EDToken::string() const {
|
||||
return Str;
|
||||
}
|
||||
|
||||
int EDToken::operandID() const {
|
||||
return OperandID;
|
||||
}
|
||||
|
||||
int EDToken::literalSign() const {
|
||||
if (Type != kTokenLiteral)
|
||||
return -1;
|
||||
return (LiteralSign ? 1 : 0);
|
||||
}
|
||||
|
||||
int EDToken::literalAbsoluteValue(uint64_t &value) const {
|
||||
if (Type != kTokenLiteral)
|
||||
return -1;
|
||||
value = LiteralAbsoluteValue;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int EDToken::registerID(unsigned ®isterID) const {
|
||||
if (Type != kTokenRegister)
|
||||
return -1;
|
||||
registerID = RegisterID;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int EDToken::tokenize(std::vector<EDToken*> &tokens,
|
||||
std::string &str,
|
||||
const char *operandOrder,
|
||||
EDDisassembler &disassembler) {
|
||||
SmallVector<MCParsedAsmOperand*, 5> parsedOperands;
|
||||
SmallVector<AsmToken, 10> asmTokens;
|
||||
|
||||
if (disassembler.parseInst(parsedOperands, asmTokens, str))
|
||||
return -1;
|
||||
|
||||
SmallVectorImpl<MCParsedAsmOperand*>::iterator operandIterator;
|
||||
unsigned int operandIndex;
|
||||
SmallVectorImpl<AsmToken>::iterator tokenIterator;
|
||||
|
||||
operandIterator = parsedOperands.begin();
|
||||
operandIndex = 0;
|
||||
|
||||
bool readOpcode = false;
|
||||
|
||||
const char *wsPointer = asmTokens.begin()->getLoc().getPointer();
|
||||
|
||||
for (tokenIterator = asmTokens.begin();
|
||||
tokenIterator != asmTokens.end();
|
||||
++tokenIterator) {
|
||||
SMLoc tokenLoc = tokenIterator->getLoc();
|
||||
|
||||
const char *tokenPointer = tokenLoc.getPointer();
|
||||
|
||||
if (tokenPointer > wsPointer) {
|
||||
unsigned long wsLength = tokenPointer - wsPointer;
|
||||
|
||||
EDToken *whitespaceToken = new EDToken(StringRef(wsPointer, wsLength),
|
||||
EDToken::kTokenWhitespace,
|
||||
0,
|
||||
disassembler);
|
||||
|
||||
tokens.push_back(whitespaceToken);
|
||||
}
|
||||
|
||||
wsPointer = tokenPointer + tokenIterator->getString().size();
|
||||
|
||||
while (operandIterator != parsedOperands.end() &&
|
||||
tokenLoc.getPointer() >
|
||||
(*operandIterator)->getEndLoc().getPointer()) {
|
||||
++operandIterator;
|
||||
++operandIndex;
|
||||
}
|
||||
|
||||
EDToken *token;
|
||||
|
||||
switch (tokenIterator->getKind()) {
|
||||
case AsmToken::Identifier:
|
||||
if (!readOpcode) {
|
||||
token = new EDToken(tokenIterator->getString(),
|
||||
EDToken::kTokenOpcode,
|
||||
(uint64_t)tokenIterator->getKind(),
|
||||
disassembler);
|
||||
readOpcode = true;
|
||||
break;
|
||||
}
|
||||
// any identifier that isn't an opcode is mere punctuation; so we fall
|
||||
// through
|
||||
default:
|
||||
token = new EDToken(tokenIterator->getString(),
|
||||
EDToken::kTokenPunctuation,
|
||||
(uint64_t)tokenIterator->getKind(),
|
||||
disassembler);
|
||||
break;
|
||||
case AsmToken::Integer:
|
||||
{
|
||||
token = new EDToken(tokenIterator->getString(),
|
||||
EDToken::kTokenLiteral,
|
||||
(uint64_t)tokenIterator->getKind(),
|
||||
disassembler);
|
||||
|
||||
int64_t intVal = tokenIterator->getIntVal();
|
||||
|
||||
if (intVal < 0)
|
||||
token->makeLiteral(true, -intVal);
|
||||
else
|
||||
token->makeLiteral(false, intVal);
|
||||
break;
|
||||
}
|
||||
case AsmToken::Register:
|
||||
{
|
||||
token = new EDToken(tokenIterator->getString(),
|
||||
EDToken::kTokenLiteral,
|
||||
(uint64_t)tokenIterator->getKind(),
|
||||
disassembler);
|
||||
|
||||
token->makeRegister((unsigned)tokenIterator->getRegVal());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (operandIterator != parsedOperands.end() &&
|
||||
tokenLoc.getPointer() >=
|
||||
(*operandIterator)->getStartLoc().getPointer()) {
|
||||
/// operandIndex == 0 means the operand is the instruction (which the
|
||||
/// AsmParser treats as an operand but edis does not). We therefore skip
|
||||
/// operandIndex == 0 and subtract 1 from all other operand indices.
|
||||
|
||||
if (operandIndex > 0)
|
||||
token->setOperandID(operandOrder[operandIndex - 1]);
|
||||
}
|
||||
|
||||
tokens.push_back(token);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int EDToken::getString(const char*& buf) {
|
||||
if (PermStr.length() == 0) {
|
||||
PermStr = Str.str();
|
||||
}
|
||||
buf = PermStr.c_str();
|
||||
return 0;
|
||||
}
|
Reference in New Issue
Block a user