Allow reading of operands with a SgAsmBinaryLsr as the root expression
[dyninst.git] / dataflowAPI / rose / semantics / BaseSemantics2.C
1 #include "../util/StringUtility.h"
2 //#include "sage3basic.h"
3 #include "BaseSemantics2.h"
4 //#include "AsmUnparser_compat.h"
5 //#include "Diagnostics.h"
6 #include "RegisterStateGeneric.h"
7 #include "../util/Message.h"
8
9 namespace rose {
10 namespace BinaryAnalysis {
11 namespace InstructionSemantics2 {
12
13 using namespace Sawyer::Message::Common;
14
15 namespace BaseSemantics {
16
17 /*******************************************************************************************************************************
18  *                                      Printing operator<<
19  *******************************************************************************************************************************/
20
21 std::ostream& operator<<(std::ostream &o, const Exception &x) {
22     x.print(o);
23     return o;
24 }
25
26 std::ostream& operator<<(std::ostream &o, const SValue &x) {
27     x.print(o);
28     return o;
29 }
30
31 std::ostream& operator<<(std::ostream &o, const SValue::WithFormatter &x)
32 {
33     x.print(o);
34     return o;
35 }
36
37 std::ostream& operator<<(std::ostream &o, const MemoryState &x) {
38     x.print(o);
39     return o;
40 }
41
42 std::ostream& operator<<(std::ostream &o, const MemoryState::WithFormatter &x)
43 {
44     x.print(o);
45     return o;
46 }
47
48 std::ostream& operator<<(std::ostream &o, const RegisterState &x) {
49     x.print(o);
50     return o;
51 }
52
53 std::ostream& operator<<(std::ostream &o, const RegisterState::WithFormatter &x)
54 {
55     x.print(o);
56     return o;
57 }
58
59 std::ostream& operator<<(std::ostream &o, const State &x) {
60     x.print(o);
61     return o;
62 }
63
64 std::ostream& operator<<(std::ostream &o, const State::WithFormatter &x)
65 {
66     x.print(o);
67     return o;
68 }
69
70 std::ostream& operator<<(std::ostream &o, const RiscOperators &x) {
71     x.print(o);
72     return o;
73 }
74
75 std::ostream& operator<<(std::ostream &o, const RiscOperators::WithFormatter &x)
76 {
77     x.print(o);
78     return o;
79 }
80
81 /*******************************************************************************************************************************
82  *                                      Exceptions
83  *******************************************************************************************************************************/
84
85 void
86 Exception::print(std::ostream &o) const
87 {
88     o <<"rose::BinaryAnalysis::InstructionSemantics::BaseSemantics::Exception: " <<what();
89     //FIXME
90     //Some mechanism for printing the instruction here
91     //if (insn)
92     //    o <<": " <<unparseInstructionWithAddress(insn);
93     o <<"\n";
94 }
95
96 /*******************************************************************************************************************************
97  *                                      MemoryState
98  *******************************************************************************************************************************/
99
100
101 /*******************************************************************************************************************************
102  *                                      State
103  *******************************************************************************************************************************/
104
105 void
106 State::clear() {
107     registers_->clear();
108     memory_->clear();
109 }
110
111 void
112 State::zero_registers() {
113     registers_->zero();
114 }
115
116 void
117 State::clear_memory() {
118     memory_->clear();
119 }
120
121 SValuePtr
122 State::readRegister(const RegisterDescriptor &desc, const SValuePtr &dflt, RiscOperators *ops) {
123     ASSERT_require(desc.is_valid());
124     ASSERT_not_null(dflt);
125     ASSERT_not_null(ops);
126     return registers_->readRegister(desc, dflt, ops);
127 }
128
129 void
130 State::writeRegister(const RegisterDescriptor &desc, const SValuePtr &value, RiscOperators *ops) {
131     ASSERT_require(desc.is_valid());
132     ASSERT_not_null(value);
133     ASSERT_not_null(ops);
134     registers_->writeRegister(desc, value, ops);
135 }
136
137 SValuePtr
138 State::readMemory(const SValuePtr &address, const SValuePtr &dflt, RiscOperators *addrOps, RiscOperators *valOps) {
139     ASSERT_not_null(address);
140     ASSERT_not_null(dflt);
141     ASSERT_not_null(addrOps);
142     ASSERT_not_null(valOps);
143     return memory_->readMemory(address, dflt, addrOps, valOps);
144 }
145
146 void
147 State::writeMemory(const SValuePtr &addr, const SValuePtr &value, RiscOperators *addrOps, RiscOperators *valOps) {
148     ASSERT_not_null(addr);
149     ASSERT_not_null(value);
150     ASSERT_not_null(addrOps);
151     ASSERT_not_null(valOps);
152     memory_->writeMemory(addr, value, addrOps, valOps);
153 }
154
155 void
156 State::printRegisters(std::ostream &stream, const std::string &prefix) {
157     Formatter fmt;
158     fmt.set_line_prefix(prefix);
159     printRegisters(stream, fmt);
160 }
161     
162 void
163 State::printRegisters(std::ostream &stream, Formatter &fmt) const {
164     registers_->print(stream, fmt);
165 }
166
167 void
168 State::printMemory(std::ostream &stream, const std::string &prefix) const {
169     Formatter fmt;
170     fmt.set_line_prefix(prefix);
171     printMemory(stream, fmt);
172 }
173
174 void
175 State::printMemory(std::ostream &stream, Formatter &fmt) const {
176     memory_->print(stream, fmt);
177 }
178
179 bool
180 State::merge(const StatePtr &other, RiscOperators *ops) {
181     bool memoryChanged = memoryState()->merge(other->memoryState(), ops, ops);
182     bool registersChanged = registerState()->merge(other->registerState(), ops);
183     return memoryChanged || registersChanged;
184 }
185
186 void
187 State::print(std::ostream &stream, const std::string &prefix) const {
188     Formatter fmt;
189     fmt.set_line_prefix(prefix);
190     print(stream, fmt);
191 }
192
193 void
194 State::print(std::ostream &stream, Formatter &fmt) const
195 {
196     std::string prefix = fmt.get_line_prefix();
197     Indent indent(fmt);
198     stream <<prefix <<"registers:\n" <<(*registers_+fmt) <<prefix <<"memory:\n" <<(*memory_+fmt);
199 }
200
201 /*******************************************************************************************************************************
202  *                                      RiscOperators
203  *******************************************************************************************************************************/
204
205 void
206 RiscOperators::startInstruction(SgAsmInstruction *insn) {
207     ASSERT_not_null(insn);
208     //FIXME
209     //Use fprintf/cout
210     //SAWYER_MESG(mlog[TRACE]) <<"starting instruction " <<unparseInstructionWithAddress(insn) <<"\n";
211     currentInsn_ = insn;
212     ++nInsns_;
213 };
214
215 SValuePtr
216 RiscOperators::subtract(const SValuePtr &minuend, const SValuePtr &subtrahend) {
217     return add(minuend, negate(subtrahend));
218 }
219
220 SValuePtr
221 RiscOperators::equal(const SValuePtr &a, const SValuePtr &b) {
222     return isEqual(a, b);
223 }
224
225 SValuePtr
226 RiscOperators::isEqual(const SValuePtr &a, const SValuePtr &b) {
227     return equalToZero(xor_(a, b));
228 }
229
230 SValuePtr
231 RiscOperators::isNotEqual(const SValuePtr &a, const SValuePtr &b) {
232     return invert(isEqual(a, b));
233 }
234
235 SValuePtr
236 RiscOperators::isUnsignedLessThan(const SValuePtr &a, const SValuePtr &b) {
237     SValuePtr wideA = unsignedExtend(a, a->get_width()+1);
238     SValuePtr wideB = unsignedExtend(b, b->get_width()+1);
239     SValuePtr diff = subtract(wideA, wideB);
240     return extract(diff, diff->get_width()-1, diff->get_width()); // A < B iff sign(wideA - wideB) == -1
241 }
242
243 SValuePtr
244 RiscOperators::isUnsignedLessThanOrEqual(const SValuePtr &a, const SValuePtr &b) {
245     return or_(isUnsignedLessThan(a, b), isEqual(a, b));
246 }
247
248 SValuePtr
249 RiscOperators::isUnsignedGreaterThan(const SValuePtr &a, const SValuePtr &b) {
250     return invert(isUnsignedLessThanOrEqual(a, b));
251 }
252
253 SValuePtr
254 RiscOperators::isUnsignedGreaterThanOrEqual(const SValuePtr &a, const SValuePtr &b) {
255     return invert(isUnsignedLessThan(a, b));
256 }
257
258 SValuePtr
259 RiscOperators::isSignedLessThan(const SValuePtr &a, const SValuePtr &b) {
260     ASSERT_require(a->get_width() == b->get_width());
261     size_t nbits = a->get_width();
262     SValuePtr aIsNeg = extract(a, nbits-1, nbits);
263     SValuePtr bIsNeg = extract(b, nbits-1, nbits);
264     SValuePtr diff = subtract(signExtend(a, nbits+1), signExtend(b, nbits+1));
265     SValuePtr diffIsNeg = extract(diff, nbits, nbits+1); // sign bit
266     SValuePtr negPos = and_(aIsNeg, invert(bIsNeg));     // A is negative and B is non-negative?
267     SValuePtr sameSigns = invert(xor_(aIsNeg, bIsNeg));  // A and B are both negative or both non-negative?
268     SValuePtr result = or_(negPos, and_(sameSigns, diffIsNeg));
269     return result;
270 }
271
272 SValuePtr
273 RiscOperators::isSignedLessThanOrEqual(const SValuePtr &a, const SValuePtr &b) {
274     return or_(isSignedLessThan(a, b), isEqual(a, b));
275 }
276
277 SValuePtr
278 RiscOperators::isSignedGreaterThan(const SValuePtr &a, const SValuePtr &b) {
279     return invert(isSignedLessThanOrEqual(a, b));
280 }
281
282 SValuePtr
283 RiscOperators::isSignedGreaterThanOrEqual(const SValuePtr &a, const SValuePtr &b) {
284     return invert(isSignedLessThan(a, b));
285 }
286
287 SValuePtr
288 RiscOperators::fpFromInteger(const SValuePtr &/*intValue*/, SgAsmFloatType *fpType) {
289     ASSERT_not_null(fpType);
290     throw NotImplemented("fpFromInteger is not implemented", currentInstruction());
291 }
292
293 SValuePtr
294 RiscOperators::fpToInteger(const SValuePtr &/*fpValue*/, SgAsmFloatType *fpType, const SValuePtr &/*dflt*/) {
295     ASSERT_not_null(fpType);
296     throw NotImplemented("fpToInteger is not implemented", currentInstruction());
297 }
298
299 SValuePtr
300 RiscOperators::fpConvert(const SValuePtr &a, SgAsmFloatType *aType, SgAsmFloatType *retType) {
301     ASSERT_not_null(a);
302     ASSERT_not_null(aType);
303     ASSERT_not_null(retType);
304     if (aType == retType)
305         return a->copy();
306     throw NotImplemented("fpConvert is not implemented", currentInstruction());
307 }
308
309 SValuePtr
310 RiscOperators::fpIsNan(const SValuePtr &a, SgAsmFloatType *aType) {
311     // Value is NAN iff exponent bits are all set and significand is not zero.
312     ASSERT_not_null(a);
313     ASSERT_not_null(aType);
314     SValuePtr exponent = extract(a, aType->exponentBits().least(), aType->exponentBits().greatest()+1);
315     SValuePtr significand = extract(a, aType->significandBits().least(), aType->significandBits().greatest()+1);
316     return and_(equalToZero(invert(exponent)), invert(equalToZero(significand)));
317 }
318
319 SValuePtr
320 RiscOperators::fpIsDenormalized(const SValuePtr &a, SgAsmFloatType *aType) {
321     // Value is denormalized iff exponent is zero and significand is not zero.
322     ASSERT_not_null(a);
323     ASSERT_not_null(aType);
324     if (!aType->gradualUnderflow())
325         return boolean_(false);
326     SValuePtr exponent = extract(a, aType->exponentBits().least(), aType->exponentBits().greatest()+1);
327     SValuePtr significand = extract(a, aType->significandBits().least(), aType->significandBits().greatest()+1);
328     return and_(equalToZero(exponent), invert(equalToZero(significand)));
329 }
330
331 SValuePtr
332 RiscOperators::fpIsZero(const SValuePtr &a, SgAsmFloatType *aType) {
333     // Value is zero iff exponent and significand are both zero.
334     ASSERT_not_null(a);
335     ASSERT_not_null(aType);
336     SValuePtr exponent = extract(a, aType->exponentBits().least(), aType->exponentBits().greatest()+1);
337     SValuePtr significand = extract(a, aType->significandBits().least(), aType->significandBits().greatest()+1);
338     return and_(equalToZero(exponent), equalToZero(significand));
339 }
340
341 SValuePtr
342 RiscOperators::fpIsInfinity(const SValuePtr &a, SgAsmFloatType *aType) {
343     // Value is infinity iff exponent bits are all set and significand is zero.
344     ASSERT_not_null(a);
345     ASSERT_not_null(aType);
346     SValuePtr exponent = extract(a, aType->exponentBits().least(), aType->exponentBits().greatest()+1);
347     SValuePtr significand = extract(a, aType->significandBits().least(), aType->significandBits().greatest()+1);
348     return and_(equalToZero(invert(exponent)), equalToZero(significand));
349 }
350
351 SValuePtr
352 RiscOperators::fpSign(const SValuePtr &a, SgAsmFloatType *aType) {
353     ASSERT_not_null(a);
354     ASSERT_not_null(aType);
355     return extract(a, aType->signBit(), aType->signBit()+1);
356 }
357
358 SValuePtr
359 RiscOperators::fpEffectiveExponent(const SValuePtr &a, SgAsmFloatType *aType) {
360     ASSERT_not_null(a);
361     ASSERT_not_null(aType);
362     size_t expWidth = aType->exponentBits().size() + 1; // add a sign bit to the beginning
363     SValuePtr storedExponent = extract(a, aType->exponentBits().least(), aType->exponentBits().greatest()+1);
364     SValuePtr significand = extract(a, aType->significandBits().least(), aType->significandBits().greatest()+1);
365     SValuePtr retval = ite(equalToZero(storedExponent),
366                            ite(equalToZero(significand),
367                                // Stored exponent and significand are both zero, therefore value is zero
368                                number_(expWidth, 0),    // value is zero, therefore exponent is zero
369
370                                // Stored exponent is zero but significand is not, therefore denormalized number.
371                                // effective exponent is 1 - bias - (significandWidth - mssb(significand))
372                                add(number_(expWidth, 1 - aType->exponentBias() - aType->significandBits().size()),
373                                    unsignedExtend(mostSignificantSetBit(significand), expWidth))),
374
375                            // Stored exponent is non-zero so significand is normalized. Effective exponent is the stored
376                            // exponent minus the bias.
377                            subtract(unsignedExtend(storedExponent, expWidth),
378                                     number_(expWidth, aType->exponentBias())));
379     return retval;
380 }
381
382 SValuePtr
383 RiscOperators::fpAdd(const SValuePtr &/*a*/, const SValuePtr &/*b*/, SgAsmFloatType */*fpType*/) {
384     throw NotImplemented("fpAdd is not implemented", currentInstruction());
385 }
386
387 SValuePtr
388 RiscOperators::fpSubtract(const SValuePtr &/*a*/, const SValuePtr &/*b*/, SgAsmFloatType */*fpType*/) {
389     throw NotImplemented("fpSubtract is not implemented", currentInstruction());
390 }
391
392 SValuePtr
393 RiscOperators::fpMultiply(const SValuePtr &/*a*/, const SValuePtr &/*b*/, SgAsmFloatType */*fpType*/) {
394     throw NotImplemented("fpMultiply is not implemented", currentInstruction());
395 }
396
397 SValuePtr
398 RiscOperators::fpDivide(const SValuePtr &/*a*/, const SValuePtr &/*b*/, SgAsmFloatType */*fpType*/) {
399     throw NotImplemented("fpDivide is not implemented", currentInstruction());
400 }
401
402 SValuePtr
403 RiscOperators::fpSquareRoot(const SValuePtr &/*a*/, SgAsmFloatType */*aType*/) {
404     throw NotImplemented("fpSquareRoot is not implemented", currentInstruction());
405 }
406
407 SValuePtr
408 RiscOperators::fpRoundTowardZero(const SValuePtr &/*a*/, SgAsmFloatType */*aType*/) {
409     throw NotImplemented("fpRoundTowardZero is not implemented", currentInstruction());
410 }
411
412 SValuePtr
413 RiscOperators::readRegister(const RegisterDescriptor &reg, const SValuePtr &dflt_) {
414     SValuePtr dflt = dflt_;
415     ASSERT_not_null(currentState_);
416     ASSERT_not_null(dflt);
417
418     // If there's an lazily-updated initial state, then get its register, updating the initial state as a side effect.
419     if (initialState_)
420         dflt = initialState()->readRegister(reg, dflt, this);
421
422     return currentState_->readRegister(reg, dflt, this);
423 }
424
425 /*******************************************************************************************************************************
426  *                                      Dispatcher
427  *******************************************************************************************************************************/
428
429 void
430 Dispatcher::advanceInstructionPointer(SgAsmInstruction *insn) {
431     RegisterDescriptor ipReg = instructionPointerRegister();
432     size_t nBits = ipReg.get_nbits();
433     BaseSemantics::SValuePtr ipValue;
434     if (!autoResetInstructionPointer_ && operators->currentState() && operators->currentState()->registerState()) {
435         BaseSemantics::RegisterStateGenericPtr grState =
436             boost::dynamic_pointer_cast<BaseSemantics::RegisterStateGeneric>(operators->currentState()->registerState());
437         if (grState && grState->is_partly_stored(ipReg))
438             ipValue = operators->readRegister(ipReg);
439     }
440     if (!ipValue)
441         ipValue = operators->number_(nBits, insn->get_address());
442     ipValue = operators->add(ipValue, operators->number_(nBits, insn->get_size()));
443     operators->writeRegister(ipReg, ipValue);
444 }
445
446 void
447 Dispatcher::addressWidth(size_t nBits) {
448     ASSERT_require2(nBits==addrWidth_ || addrWidth_==0, "address width cannot be changed once it is set");
449     addrWidth_ = nBits;
450 }
451
452 void
453 Dispatcher::processInstruction(SgAsmInstruction *insn)
454 {
455     operators->startInstruction(insn);
456     InsnProcessor *iproc = iproc_lookup(insn);
457     try {
458         if (!iproc)
459             throw Exception("no dispatch ability for instruction", insn);
460         iproc->process(shared_from_this(), insn);
461     } catch (Exception &e) {
462         // If the exception was thrown by something that didn't have an instruction available, then add the instruction
463         if (!e.insn)
464             e.insn = insn;
465         throw e;
466     }
467     operators->finishInstruction(insn);
468 }
469
470 InsnProcessor *
471 Dispatcher::iproc_lookup(SgAsmInstruction *insn)
472 {
473     int key = iproc_key(insn);
474     ASSERT_require(key>=0);
475     return iproc_get(key);
476 }
477
478 void
479 Dispatcher::iproc_replace(SgAsmInstruction *insn, InsnProcessor *iproc)
480 {
481     iproc_set(iproc_key(insn), iproc);
482 }
483
484 void
485 Dispatcher::iproc_set(int key, InsnProcessor *iproc)
486 {
487     ASSERT_require(key>=0);
488     if ((size_t)key>=iproc_table.size())
489         iproc_table.resize(key+1, NULL);
490     iproc_table[key] = iproc;
491 }
492     
493 InsnProcessor *
494 Dispatcher::iproc_get(int key)
495 {
496     if (key<0 || (size_t)key>=iproc_table.size())
497         return NULL;
498     return iproc_table[key];
499 }
500
501 const RegisterDescriptor &
502 Dispatcher::findRegister(const std::string &regname, size_t nbits/*=0*/, bool allowMissing) const
503 {
504     const RegisterDictionary *regdict = get_register_dictionary();
505     if (!regdict)
506         throw Exception("no register dictionary", currentInstruction());
507
508     const RegisterDescriptor *reg = regdict->lookup(regname);
509     if (!reg) {
510         if (allowMissing) {
511             static const RegisterDescriptor invalidRegister;
512             return invalidRegister;
513         }
514         std::ostringstream ss;
515         ss <<"Invalid register \"" <<regname <<"\" in dictionary \"" <<regdict->get_architecture_name() <<"\"";
516         throw Exception(ss.str(), currentInstruction());
517     }
518
519     if (nbits>0 && reg->get_nbits()!=nbits) {
520         std::ostringstream ss;
521         ss <<"Invalid " <<nbits <<"-bit register: \"" <<regname <<"\" is "
522            <<reg->get_nbits() <<" " <<(1==reg->get_nbits()?"byte":"bytes");
523         throw Exception(ss.str(), currentInstruction());
524     }
525     return *reg;
526 }
527
528 void
529 Dispatcher::decrementRegisters(SgAsmExpression */*e*/)
530 {
531     /*struct T1: AstSimpleProcessing {
532         RiscOperatorsPtr ops;
533         T1(const RiscOperatorsPtr &ops): ops(ops) {}
534         void visit(SgNode *node) {
535             if (SgAsmRegisterReferenceExpression *rre = isSgAsmRegisterReferenceExpression(node)) {
536                 const RegisterDescriptor &reg = rre->get_descriptor();
537                 if (rre->get_adjustment() < 0) {
538                     SValuePtr adj = ops->number_(64, (int64_t)rre->get_adjustment());
539                     if (reg.get_nbits() <= 64) {
540                         adj = ops->unsignedExtend(adj, reg.get_nbits());  // truncate
541                     } else {
542                         adj = ops->signExtend(adj, reg.get_nbits());      // extend
543                     }
544                     ops->writeRegister(reg, ops->add(ops->readRegister(reg), adj));
545                 }
546             }
547         }
548     } t1(operators);
549     t1.traverse(e, preorder);*/
550 }
551
552 void
553 Dispatcher::incrementRegisters(SgAsmExpression */*e*/)
554 {
555     /*struct T1: AstSimpleProcessing {
556         RiscOperatorsPtr ops;
557         T1(const RiscOperatorsPtr &ops): ops(ops) {}
558         void visit(SgNode *node) {
559             if (SgAsmRegisterReferenceExpression *rre = isSgAsmRegisterReferenceExpression(node)) {
560                 const RegisterDescriptor &reg = rre->get_descriptor();
561                 if (rre->get_adjustment() > 0) {
562                     SValuePtr adj = ops->unsignedExtend(ops->number_(64, (int64_t)rre->get_adjustment()), reg.get_nbits());
563                     ops->writeRegister(reg, ops->add(ops->readRegister(reg), adj));
564                 }
565             }
566         }
567     } t1(operators);
568     t1.traverse(e, preorder);*/
569 }
570
571 SValuePtr
572 Dispatcher::effectiveAddress(SgAsmExpression *e, size_t nbits/*=0*/)
573 {
574     BaseSemantics::SValuePtr retval;
575 #if 1 // DEBUGGING [Robb P. Matzke 2015-08-04]
576     ASSERT_always_require(retval==NULL);
577 #endif
578     if (0==nbits)
579         nbits = addressWidth();
580
581     if (SgAsmMemoryReferenceExpression *mre = isSgAsmMemoryReferenceExpression(e)) {
582         retval = effectiveAddress(mre->get_address(), nbits);
583     } else if (SgAsmRegisterReferenceExpression *rre = isSgAsmRegisterReferenceExpression(e)) {
584         const RegisterDescriptor &reg = rre->get_descriptor();
585         retval = operators->readRegister(reg);
586     } else if (SgAsmBinaryAdd *op = isSgAsmBinaryAdd(e)) {
587         BaseSemantics::SValuePtr lhs = effectiveAddress(op->get_lhs(), nbits);
588         BaseSemantics::SValuePtr rhs = effectiveAddress(op->get_rhs(), nbits);
589         retval = operators->add(lhs, rhs);
590     } else if (SgAsmBinaryMultiply *op = isSgAsmBinaryMultiply(e)) {
591         BaseSemantics::SValuePtr lhs = effectiveAddress(op->get_lhs(), nbits);
592         BaseSemantics::SValuePtr rhs = effectiveAddress(op->get_rhs(), nbits);
593         retval = operators->unsignedMultiply(lhs, rhs);
594     } else if (SgAsmIntegerValueExpression *ival = isSgAsmIntegerValueExpression(e)) {
595         retval = operators->number_(ival->get_significantBits(), ival->get_value());
596     }
597
598     ASSERT_not_null(retval);
599     if (retval->get_width() < nbits) {
600         retval = operators->signExtend(retval, nbits);
601     } else if (retval->get_width() > nbits) {
602         retval = operators->extract(retval, 0, nbits);
603     }
604     return retval;
605 }
606
607 RegisterDescriptor
608 Dispatcher::segmentRegister(SgAsmMemoryReferenceExpression *mre)
609 {
610     if (mre!=NULL && mre->get_segment()!=NULL) {
611         if (SgAsmRegisterReferenceExpression *rre = isSgAsmRegisterReferenceExpression(mre->get_segment())) {
612             return rre->get_descriptor();
613         }
614     }
615     return RegisterDescriptor();
616 }
617
618 void
619 Dispatcher::write(SgAsmExpression *e, const SValuePtr &value, size_t addr_nbits/*=0*/)
620 {
621     ASSERT_not_null(e);
622     ASSERT_not_null(value);
623     if (SgAsmDirectRegisterExpression *re = isSgAsmDirectRegisterExpression(e)) {
624         operators->writeRegister(re->get_descriptor(), value);
625     } else if (SgAsmIndirectRegisterExpression *re = isSgAsmIndirectRegisterExpression(e)) {
626         SValuePtr offset = operators->readRegister(re->get_offset());
627         if (!offset->is_number()) {
628             std::string offset_name = get_register_dictionary()->lookup(re->get_offset());
629             offset_name = offset_name.empty() ? "" : "(" + offset_name + ") ";
630             throw Exception("indirect register offset " + offset_name + "must have a concrete value", NULL);
631         }
632         size_t idx = (offset->get_number() + re->get_index()) % re->get_modulus();
633         RegisterDescriptor reg = re->get_descriptor();
634         reg.set_major(reg.get_major() + re->get_stride().get_major() * idx);
635         reg.set_minor(reg.get_minor() + re->get_stride().get_minor() * idx);
636         reg.set_offset(reg.get_offset() + re->get_stride().get_offset() * idx);
637         reg.set_nbits(reg.get_nbits() + re->get_stride().get_nbits() * idx);
638         operators->writeRegister(reg, value);
639     } else if (SgAsmMemoryReferenceExpression *mre = isSgAsmMemoryReferenceExpression(e)) {
640         SValuePtr addr = effectiveAddress(mre, addr_nbits);
641         ASSERT_require(0==addrWidth_ || addr->get_width()==addrWidth_);
642         operators->writeMemory(segmentRegister(mre), addr, value, operators->boolean_(true));
643     } else {
644         ASSERT_not_implemented("[Robb P. Matzke 2014-10-07]");
645     }
646 }
647
648 SValuePtr
649 Dispatcher::read(SgAsmExpression *e, size_t value_nbits/*=0*/, size_t addr_nbits/*=0*/)
650 {
651     ASSERT_not_null(e);
652     if (0 == value_nbits) {
653         SgAsmType *expr_type = e->get_type();
654         ASSERT_not_null(expr_type);
655         value_nbits = expr_type->get_nBits();
656         ASSERT_require(value_nbits != 0);
657     }
658
659     SValuePtr retval;
660     if (SgAsmDirectRegisterExpression *re = isSgAsmDirectRegisterExpression(e)) {
661         retval = operators->readRegister(re->get_descriptor());
662     } else if (SgAsmIndirectRegisterExpression *re = isSgAsmIndirectRegisterExpression(e)) {
663         SValuePtr offset = operators->readRegister(re->get_offset());
664         if (!offset->is_number()) {
665             std::string offset_name = get_register_dictionary()->lookup(re->get_offset());
666             offset_name = offset_name.empty() ? "" : "(" + offset_name + ") ";
667             throw Exception("indirect register offset " + offset_name + "must have a concrete value", NULL);
668         }
669         size_t idx = (offset->get_number() + re->get_index()) % re->get_modulus();
670         RegisterDescriptor reg = re->get_descriptor();
671         reg.set_major(reg.get_major() + re->get_stride().get_major() * idx);
672         reg.set_minor(reg.get_minor() + re->get_stride().get_minor() * idx);
673         reg.set_offset(reg.get_offset() + re->get_stride().get_offset() * idx);
674         reg.set_nbits(reg.get_nbits() + re->get_stride().get_nbits() * idx);
675         retval = operators->readRegister(reg);
676     } else if (SgAsmMemoryReferenceExpression *mre = isSgAsmMemoryReferenceExpression(e)) {
677         BaseSemantics::SValuePtr addr = effectiveAddress(mre, addr_nbits);
678         ASSERT_require(0==addrWidth_ || addr->get_width()==addrWidth_);
679         BaseSemantics::SValuePtr dflt = undefined_(value_nbits);
680         retval = operators->readMemory(segmentRegister(mre), addr, dflt, operators->boolean_(true));
681     } else if (SgAsmValueExpression *ve = isSgAsmValueExpression(e)) {
682         uint64_t val = SageInterface::getAsmSignedConstant(ve);
683         retval = operators->number_(value_nbits, val);
684     } else if (SgAsmBinaryAdd *sum = isSgAsmBinaryAdd(e)) {
685         SgAsmExpression *lhs = sum->get_lhs();
686         SgAsmExpression *rhs = sum->get_rhs();
687         size_t nbits = std::max(lhs->get_nBits(), rhs->get_nBits());
688         retval = operators->add(operators->signExtend(read(lhs, lhs->get_nBits(), addr_nbits), nbits),
689                                 operators->signExtend(read(rhs, rhs->get_nBits(), addr_nbits), nbits));
690     } else if (SgAsmBinaryMultiply *product = isSgAsmBinaryMultiply(e)) {
691         SgAsmExpression *lhs = product->get_lhs();
692         SgAsmExpression *rhs = product->get_rhs();
693         retval = operators->unsignedMultiply(read(lhs, lhs->get_nBits()), read(rhs, rhs->get_nBits()));
694     } else if (SgAsmBinaryLsl *lshift = isSgAsmBinaryLsl(e)) {
695         SgAsmExpression *lhs = lshift->get_lhs();
696         SgAsmExpression *rhs = lshift->get_rhs();
697         size_t nbits = std::max(lhs->get_nBits(), rhs->get_nBits());
698         retval = operators->shiftLeft(read(lhs, lhs->get_nBits()), read(rhs, rhs->get_nBits()));
699     } else if(SgAsmBinaryAsr *asr = isSgAsmBinaryAsr(e)) {
700         SgAsmExpression *lhs = asr->get_lhs();
701         SgAsmExpression *rhs = asr->get_rhs();
702         retval = operators->shiftRightArithmetic(read(lhs, lhs->get_nBits()), read(rhs, rhs->get_nBits()));
703     } else if(SgAsmBinaryLsr *lsr = isSgAsmBinaryLsr(e)) {
704         SgAsmExpression *lhs = lsr->get_lhs();
705         SgAsmExpression *rhs = lsr->get_rhs();
706         retval = operators->shiftRight(read(lhs, lhs->get_nBits()), read(rhs, rhs->get_nBits()));
707     } else {
708         ASSERT_not_implemented(e->class_name());
709     }
710
711     // Make sure the return value is the requested width. The unsignedExtend() can expand or shrink values.
712     ASSERT_not_null(retval);
713     if (retval->get_width()!=value_nbits)
714         retval = operators->unsignedExtend(retval, value_nbits);
715     return retval;
716 }
717     
718 } // namespace
719 } // namespace
720 } // namespace
721 } // namespace