1 //===-- EDToken.cpp - LLVM Enhanced Disassembler --------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file implements the Enhanced Disassembler library's token class. The
11 // token is responsible for vending information about the token, such as its
12 // type and logical value.
14 //===----------------------------------------------------------------------===//
17 #include "EDDisassembler.h"
18 #include "llvm/MC/MCParser/MCAsmLexer.h"
19 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
20 #include "llvm/ADT/SmallVector.h"
23 EDToken::EDToken(StringRef str
,
26 EDDisassembler
&disassembler
) :
27 Disassembler(disassembler
),
37 void EDToken::makeLiteral(bool sign
, uint64_t absoluteValue
) {
40 LiteralAbsoluteValue
= absoluteValue
;
43 void EDToken::makeRegister(unsigned registerID
) {
44 Type
= kTokenRegister
;
45 RegisterID
= registerID
;
48 void EDToken::setOperandID(int operandID
) {
49 OperandID
= operandID
;
52 enum EDToken::tokenType
EDToken::type() const {
56 uint64_t EDToken::localType() const {
60 StringRef
EDToken::string() const {
64 int EDToken::operandID() const {
68 int EDToken::literalSign() const {
69 if (Type
!= kTokenLiteral
)
71 return (LiteralSign
? 1 : 0);
74 int EDToken::literalAbsoluteValue(uint64_t &value
) const {
75 if (Type
!= kTokenLiteral
)
77 value
= LiteralAbsoluteValue
;
81 int EDToken::registerID(unsigned ®isterID
) const {
82 if (Type
!= kTokenRegister
)
84 registerID
= RegisterID
;
88 int EDToken::tokenize(std::vector
<EDToken
*> &tokens
,
90 const char *operandOrder
,
91 EDDisassembler
&disassembler
) {
92 SmallVector
<MCParsedAsmOperand
*, 5> parsedOperands
;
93 SmallVector
<AsmToken
, 10> asmTokens
;
95 if (disassembler
.parseInst(parsedOperands
, asmTokens
, str
))
98 SmallVectorImpl
<MCParsedAsmOperand
*>::iterator operandIterator
;
99 unsigned int operandIndex
;
100 SmallVectorImpl
<AsmToken
>::iterator tokenIterator
;
102 operandIterator
= parsedOperands
.begin();
105 bool readOpcode
= false;
107 const char *wsPointer
= asmTokens
.begin()->getLoc().getPointer();
109 for (tokenIterator
= asmTokens
.begin();
110 tokenIterator
!= asmTokens
.end();
112 SMLoc tokenLoc
= tokenIterator
->getLoc();
114 const char *tokenPointer
= tokenLoc
.getPointer();
116 if (tokenPointer
> wsPointer
) {
117 unsigned long wsLength
= tokenPointer
- wsPointer
;
119 EDToken
*whitespaceToken
= new EDToken(StringRef(wsPointer
, wsLength
),
120 EDToken::kTokenWhitespace
,
124 tokens
.push_back(whitespaceToken
);
127 wsPointer
= tokenPointer
+ tokenIterator
->getString().size();
129 while (operandIterator
!= parsedOperands
.end() &&
130 tokenLoc
.getPointer() >
131 (*operandIterator
)->getEndLoc().getPointer()) {
138 switch (tokenIterator
->getKind()) {
139 case AsmToken::Identifier
:
141 token
= new EDToken(tokenIterator
->getString(),
142 EDToken::kTokenOpcode
,
143 (uint64_t)tokenIterator
->getKind(),
148 // any identifier that isn't an opcode is mere punctuation; so we fall
151 token
= new EDToken(tokenIterator
->getString(),
152 EDToken::kTokenPunctuation
,
153 (uint64_t)tokenIterator
->getKind(),
156 case AsmToken::Integer
:
158 token
= new EDToken(tokenIterator
->getString(),
159 EDToken::kTokenLiteral
,
160 (uint64_t)tokenIterator
->getKind(),
163 int64_t intVal
= tokenIterator
->getIntVal();
166 token
->makeLiteral(true, -intVal
);
168 token
->makeLiteral(false, intVal
);
171 case AsmToken::Register
:
173 token
= new EDToken(tokenIterator
->getString(),
174 EDToken::kTokenLiteral
,
175 (uint64_t)tokenIterator
->getKind(),
178 token
->makeRegister((unsigned)tokenIterator
->getRegVal());
183 if (operandIterator
!= parsedOperands
.end() &&
184 tokenLoc
.getPointer() >=
185 (*operandIterator
)->getStartLoc().getPointer()) {
186 /// operandIndex == 0 means the operand is the instruction (which the
187 /// AsmParser treats as an operand but edis does not). We therefore skip
188 /// operandIndex == 0 and subtract 1 from all other operand indices.
190 if (operandIndex
> 0)
191 token
->setOperandID(operandOrder
[operandIndex
- 1]);
194 tokens
.push_back(token
);
197 // Free any parsed operands.
198 for (unsigned i
= 0, e
= parsedOperands
.size(); i
!= e
; ++i
)
199 delete parsedOperands
[i
];
204 int EDToken::getString(const char*& buf
) {
205 if (PermStr
.length() == 0) {
208 buf
= PermStr
.c_str();