Added the enhanced disassembly library's implementation and
[oota-llvm.git] / tools / ed / EDToken.cpp
1 //===-EDToken.cpp - LLVM Enhanced Disassembler ----------------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 // 
8 //===----------------------------------------------------------------------===//
9 //
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.
13 //
14 //===----------------------------------------------------------------------===//
15
16 #include "EDDisassembler.h"
17 #include "EDToken.h"
18
19 #include "llvm/ADT/SmallVector.h"
20 #include "llvm/MC/MCParser/MCAsmLexer.h"
21 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
22
23 using namespace llvm;
24
25 EDToken::EDToken(StringRef str,
26                  enum tokenType type,
27                  uint64_t localType,
28                  EDDisassembler &disassembler) :
29   Disassembler(disassembler),
30   Str(str),
31   Type(type),
32   LocalType(localType),
33   OperandID(-1) {
34 }
35
36 EDToken::~EDToken() {
37 }
38
39 void EDToken::makeLiteral(bool sign, uint64_t absoluteValue) {
40   Type = kTokenLiteral;
41   LiteralSign = sign;
42   LiteralAbsoluteValue = absoluteValue;
43 }
44
45 void EDToken::makeRegister(unsigned registerID) {
46   Type = kTokenRegister;
47   RegisterID = registerID;
48 }
49
50 void EDToken::setOperandID(int operandID) {
51   OperandID = operandID;
52 }
53
54 enum EDToken::tokenType EDToken::type() const {
55   return Type;
56 }
57
58 uint64_t EDToken::localType() const {
59   return LocalType;
60 }
61
62 StringRef EDToken::string() const {
63   return Str;
64 }
65
66 int EDToken::operandID() const {
67   return OperandID;
68 }
69
70 int EDToken::literalSign() const {
71   if(Type != kTokenLiteral)
72     return -1;
73   return (LiteralSign ? 1 : 0);
74 }
75
76 int EDToken::literalAbsoluteValue(uint64_t &value) const {
77   if(Type != kTokenLiteral)
78     return -1;
79   value = LiteralAbsoluteValue;
80   return 0;
81 }
82
83 int EDToken::registerID(unsigned &registerID) const {
84   if(Type != kTokenRegister)
85     return -1;
86   registerID = RegisterID;
87   return 0;
88 }
89
90 int EDToken::tokenize(std::vector<EDToken*> &tokens,
91                       std::string &str,
92                       const char *operandOrder,
93                       EDDisassembler &disassembler) {
94   SmallVector<MCParsedAsmOperand*, 5> parsedOperands;
95   SmallVector<AsmToken, 10> asmTokens;
96   
97   disassembler.parseInst(parsedOperands, asmTokens, str);
98   
99   SmallVectorImpl<MCParsedAsmOperand*>::iterator operandIterator;
100   unsigned int operandIndex;
101   SmallVectorImpl<AsmToken>::iterator tokenIterator;
102   
103   operandIterator = parsedOperands.begin();
104   operandIndex = 0;
105   
106   bool readOpcode = false;
107   
108   for (tokenIterator = asmTokens.begin();
109        tokenIterator != asmTokens.end();
110        ++tokenIterator) {
111     SMLoc tokenLoc = tokenIterator->getLoc();
112     
113     while (operandIterator != parsedOperands.end() &&
114            tokenLoc.getPointer() > 
115            (*operandIterator)->getEndLoc().getPointer()) {
116       ++operandIterator;
117       ++operandIndex;
118     }
119     
120     EDToken *token;
121     
122     switch (tokenIterator->getKind()) {
123     case AsmToken::Identifier:
124       if (!readOpcode) {
125         token = new EDToken(tokenIterator->getString(),
126                             EDToken::kTokenOpcode,
127                             (uint64_t)tokenIterator->getKind(),
128                             disassembler);
129         readOpcode = true;
130         break;
131       }
132       // any identifier that isn't an opcode is mere punctuation; so we fall
133       // through
134     default:
135       token = new EDToken(tokenIterator->getString(),
136                           EDToken::kTokenPunctuation,
137                           (uint64_t)tokenIterator->getKind(),
138                           disassembler);
139       break;
140     case AsmToken::Integer:
141     {
142       token = new EDToken(tokenIterator->getString(),
143                           EDToken::kTokenLiteral,
144                           (uint64_t)tokenIterator->getKind(),
145                           disassembler);
146         
147       int64_t intVal = tokenIterator->getIntVal();
148       
149       if(intVal < 0)  
150         token->makeLiteral(true, -intVal);
151       else
152         token->makeLiteral(false, intVal);
153       break;
154     }
155     case AsmToken::Register:
156     {
157       token = new EDToken(tokenIterator->getString(),
158                           EDToken::kTokenLiteral,
159                           (uint64_t)tokenIterator->getKind(),
160                           disassembler);
161       
162       token->makeRegister((unsigned)tokenIterator->getRegVal());
163       break;
164     }
165     }
166     
167     if(operandIterator != parsedOperands.end() &&
168        tokenLoc.getPointer() >= 
169        (*operandIterator)->getStartLoc().getPointer()) {
170       token->setOperandID(operandOrder[operandIndex]);
171     }
172     
173     tokens.push_back(token);
174   }
175   
176   return 0;
177 }
178
179 int EDToken::getString(const char*& buf) {
180   if(PermStr.length() == 0) {
181     PermStr = Str.str();
182   }
183   buf = PermStr.c_str();
184   return 0;
185 }