1. Enables new jump table analysis for powerpc 2. Fix various inconsistency between...
[dyninst.git] / dataflowAPI / rose / semantics / SymEvalSemantics.C
1 //
2 // Created by ssunny on 7/1/16.
3 //
4
5 #include <Register.h>
6 #include "SymEvalSemantics.h"
7
8 using namespace rose::BinaryAnalysis::InstructionSemantics2;
9
10 ///////////////////////////////////////////////////////
11 //                                           StateAST
12 ///////////////////////////////////////////////////////
13
14 BaseSemantics::SValuePtr SymEvalSemantics::StateAST::readRegister(const RegisterDescriptor &desc,
15                                                                     const BaseSemantics::SValuePtr &/*dflt*/, BaseSemantics::RiscOperators */*ops*/) {
16     ASSERT_require(desc.is_valid());
17     SymEvalSemantics::RegisterStateASTPtr registers = SymEvalSemantics::RegisterStateAST::promote(registerState());
18     return registers->readRegister(desc, addr);
19 }
20
21 void SymEvalSemantics::StateAST::writeRegister(const RegisterDescriptor &reg, const BaseSemantics::SValuePtr &value,
22                                                  BaseSemantics::RiscOperators */*ops*/) {
23     ASSERT_require(reg.is_valid());
24     ASSERT_not_null(value);
25     SymEvalSemantics::RegisterStateASTPtr registers = SymEvalSemantics::RegisterStateAST::promote(registerState());
26     registers->writeRegister(reg, value, res, aaMap);
27 }
28
29 BaseSemantics::SValuePtr SymEvalSemantics::StateAST::readMemory(const BaseSemantics::SValuePtr &address,
30                                                                   const BaseSemantics::SValuePtr &/*dflt*/,
31                                                                   BaseSemantics::RiscOperators */*addrOps*/,
32                                                                   BaseSemantics::RiscOperators */*valOps*/,
33                                                                   size_t readSize) {
34     ASSERT_not_null(address);
35     SymEvalSemantics::MemoryStateASTPtr memory = SymEvalSemantics::MemoryStateAST::promote(memoryState());
36     return memory->readMemory(address, readSize);
37 }
38
39 void SymEvalSemantics::StateAST::writeMemory(const BaseSemantics::SValuePtr &addr,
40                                                const BaseSemantics::SValuePtr &value,
41                                                BaseSemantics::RiscOperators */*addrOps*/,
42                                                BaseSemantics::RiscOperators */*valOps*/,
43                                                size_t writeSize) {
44     ASSERT_not_null(addr);
45     ASSERT_not_null(value);
46     SymEvalSemantics::MemoryStateASTPtr memory = SymEvalSemantics::MemoryStateAST::promote(memoryState());
47     memory->writeMemory(addr, value, res, aaMap, writeSize);
48 }
49
50 void SymEvalSemantics::StateAST::writeMemory(const BaseSemantics::SValuePtr &addr, 
51                                              const BaseSemantics::SValuePtr &value,
52                                              BaseSemantics::RiscOperators *addrOps, 
53                                              BaseSemantics::RiscOperators *valOps) {
54     ASSERT_not_null(addr);
55     ASSERT_not_null(value);
56     SymEvalSemantics::MemoryStateASTPtr memory = SymEvalSemantics::MemoryStateAST::promote(memoryState());
57     memory->writeMemory(addr, value, res, aaMap, value->get_width());
58 }                                           
59
60
61
62 ///////////////////////////////////////////////////////
63 //                                   RegisterStateAST
64 ///////////////////////////////////////////////////////
65
66 BaseSemantics::SValuePtr SymEvalSemantics::RegisterStateAST::readRegister(const RegisterDescriptor &reg,
67                                                                             Dyninst::Address addr) {
68     return SymEvalSemantics::SValue::instance(wrap(convert(reg), addr));
69 }
70
71 BaseSemantics::SValuePtr SymEvalSemantics::RegisterStateAST::readRegister(const RegisterDescriptor &reg,
72                                                                             const BaseSemantics::SValuePtr &/*dflt*/,
73                                                                             BaseSemantics::RiscOperators */*ops*/) {
74     ASSERT_always_forbid("overridden RegisterState::readRegister() should never be called for AST, always use the non-virtual readRegister that takes Dyninst::Address as an argument.");
75 }
76
77 void SymEvalSemantics::RegisterStateAST::writeRegister(const RegisterDescriptor &reg,
78                                                          const BaseSemantics::SValuePtr &value,
79                                                          Dyninst::DataflowAPI::Result_t &res,
80                                                          std::map<Dyninst::Absloc, Dyninst::Assignment::Ptr> &aaMap) {
81     std::map<Dyninst::Absloc, Dyninst::Assignment::Ptr>::iterator i = aaMap.find(convert(reg));
82     if (i != aaMap.end()) {
83         SymEvalSemantics::SValuePtr value_ = SymEvalSemantics::SValue::promote(value);
84         res[i->second] = value_->get_expression();
85     }
86 }
87
88 void SymEvalSemantics::RegisterStateAST::writeRegister(const RegisterDescriptor &/*reg*/,
89                                                          const BaseSemantics::SValuePtr &/*value*/,
90                                                          BaseSemantics::RiscOperators */*ops*/) {
91     ASSERT_always_forbid("overridden RegisterState::writeRegister() should never be called for AST, always use the non-virtual writeRegister that also takes additional parameters.");
92 }
93
94 Dyninst::Absloc SymEvalSemantics::RegisterStateAST::convert(const RegisterDescriptor &reg) {
95     ASSERT_always_forbid("converting ROSE register to Dyninst register is platform specific, should not call this base class method.");
96 }
97
98 Dyninst::Absloc SymEvalSemantics::RegisterStateASTARM64::convert(const RegisterDescriptor &reg) {
99     Dyninst::MachRegister mreg;
100
101     unsigned int major = reg.get_major();
102     unsigned int size = reg.get_nbits();
103
104     switch (major) {
105         case armv8_regclass_gpr: {
106             unsigned int minor = reg.get_minor();
107
108             if (minor == armv8_gpr_zr) {
109                 mreg = Dyninst::MachRegister((size == 32) ? Dyninst::aarch64::wzr : Dyninst::aarch64::xzr);
110             } else {
111                 Dyninst::MachRegister base = (size == 32) ? Dyninst::aarch64::w0 : Dyninst::aarch64::x0;
112                 mreg = Dyninst::MachRegister(base.val() + (minor - armv8_gpr_r0));
113             }
114         }
115             break;
116         case armv8_regclass_simd_fpr: {
117             Dyninst::MachRegister base;
118             unsigned int minor = reg.get_minor();
119
120             switch(size) {
121                 case 8: base = Dyninst::aarch64::b0;
122                     break;
123                 case 16: base = Dyninst::aarch64::h0;
124                     break;
125                 case 32: base = Dyninst::aarch64::s0;
126                     break;
127                 case 64:
128                     if (reg.get_offset() == 64) {
129                         base = Dyninst::aarch64::hq0;
130                     } else {
131                         base = Dyninst::aarch64::d0;
132                     }
133                     break;
134                 case 128: base = Dyninst::aarch64::q0;
135                     break;
136                 default:assert(!"invalid size of RegisterDescriptor!");
137                     break;
138             }
139             mreg = Dyninst::MachRegister(base.val() + (minor - armv8_simdfpr_v0));
140         }
141             break;
142         case armv8_regclass_pc:
143             mreg = Dyninst::MachRegister(Dyninst::aarch64::pc);
144             break;
145         case armv8_regclass_sp:
146             mreg = Dyninst::MachRegister((size == 32) ? Dyninst::aarch64::wsp : Dyninst::aarch64::sp);
147             break;
148         case armv8_regclass_pstate: {
149             unsigned int offset = reg.get_offset();
150             switch (offset) {
151                 case armv8_pstatefield_n:
152                     mreg = Dyninst::MachRegister(Dyninst::aarch64::n);
153                     break;
154                 case armv8_pstatefield_z:
155                     mreg = Dyninst::MachRegister(Dyninst::aarch64::z);
156                     break;
157                 case armv8_pstatefield_c:
158                     mreg = Dyninst::MachRegister(Dyninst::aarch64::c);
159                     break;
160                 case armv8_pstatefield_v:
161                     mreg = Dyninst::MachRegister(Dyninst::aarch64::v);
162                     break;
163                 default:
164                     ASSERT_always_forbid("No part of the PSTATE register other than NZCV should be used.");
165                     break;
166             }
167         }
168             break;
169         default:
170             ASSERT_always_forbid("Unexpected register major type.");
171     }
172
173     return Dyninst::Absloc(mreg);
174 }
175
176 Dyninst::Absloc SymEvalSemantics::RegisterStateASTPPC32::convert(const RegisterDescriptor &reg) {
177     Dyninst::MachRegister mreg;
178
179     unsigned int major = reg.get_major();
180     unsigned int size = reg.get_nbits();
181
182     switch (major) {
183         case powerpc_regclass_gpr: {
184             unsigned int minor = reg.get_minor();
185             Dyninst::MachRegister base = Dyninst::ppc32::r0;
186
187             // For some reason, ROSE does not provide a enum representation for power registers
188             mreg = Dyninst::MachRegister(base.val() + minor);
189         }
190             break;
191         case powerpc_regclass_fpr: {
192             Dyninst::MachRegister base = Dyninst::ppc32::fpr0;
193             unsigned int minor = reg.get_minor();
194             mreg = Dyninst::MachRegister(base.val() + minor);
195         }
196             break;
197             
198         case powerpc_regclass_cr: {
199             unsigned int offset = reg.get_offset();
200             if (size == 32) {
201                 mreg = Dyninst::ppc32::cr;
202             }if (size == 4) {
203                 Dyninst::MachRegister base = Dyninst::ppc32::cr0;
204                 mreg = Dyninst::MachRegister(base.val() + offset / 4);
205             } else if (size == 1) {
206                 Dyninst::MachRegister base = Dyninst::ppc32::cr0l;
207                 mreg = Dyninst::MachRegister(base.val() + offset);
208             } else {
209                 assert(!"bad cr register size");
210             }
211         }
212             break;
213         
214         case powerpc_regclass_fpscr:
215             assert(!"not implemented register class fpscr");
216             break;
217
218         case powerpc_regclass_spr: {
219             unsigned int minor = reg.get_minor();
220             switch (minor) {
221                 case powerpc_spr_xer: 
222                     mreg = Dyninst::ppc32::xer;
223                     break;
224                 case powerpc_spr_lr:
225                     mreg = Dyninst::ppc32::lr;
226                     break;
227                 case powerpc_spr_ctr:
228                     mreg = Dyninst::ppc32::ctr;
229                     break;
230                 case powerpc_spr_dsisr:
231                     mreg = Dyninst::ppc32::dsisr;
232                     break;
233                 case powerpc_spr_dar:
234                     mreg = Dyninst::ppc32::dar;
235                     break;
236                 case powerpc_spr_dec:
237                     mreg = Dyninst::ppc32::dec;
238                     break;
239                 default:
240                     assert(!"not implemented special register");
241             }
242         }
243             break;
244         case powerpc_regclass_tbr:
245             assert(!"not implemented regclass tbr");
246             break;
247         
248         case powerpc_regclass_msr:
249             mreg = Dyninst::ppc32::msr;
250             break;
251             
252         case powerpc_regclass_sr:
253             assert(!"not implemented regclass sr");
254             break;
255
256         case powerpc_regclass_iar:
257             mreg = Dyninst::ppc32::pc;
258             break;
259             
260         case powerpc_regclass_pvr:
261             mreg = Dyninst::ppc32::pvr;
262             break;
263         default:
264             ASSERT_always_forbid("Unexpected register major type.");
265     }
266
267     return Dyninst::Absloc(mreg);
268 }
269
270 Dyninst::Absloc SymEvalSemantics::RegisterStateASTPPC64::convert(const RegisterDescriptor &reg) {
271     Dyninst::MachRegister mreg;
272
273     unsigned int major = reg.get_major();
274     unsigned int size = reg.get_nbits();
275
276     switch (major) {
277         case powerpc_regclass_gpr: {
278             unsigned int minor = reg.get_minor();
279             Dyninst::MachRegister base = Dyninst::ppc64::r0;
280
281             // For some reason, ROSE does not provide a enum representation for power registers
282             mreg = Dyninst::MachRegister(base.val() + minor);
283         }
284             break;
285         case powerpc_regclass_fpr: {
286             Dyninst::MachRegister base = Dyninst::ppc64::fpr0;
287             unsigned int minor = reg.get_minor();
288             mreg = Dyninst::MachRegister(base.val() + minor);
289         }
290             break;
291             
292         case powerpc_regclass_cr: {
293             unsigned int offset = reg.get_offset();
294             if (size == 32) {
295                 mreg = Dyninst::ppc64::cr;
296             } else if (size == 4) {
297                 Dyninst::MachRegister base = Dyninst::ppc64::cr0;
298                 mreg = Dyninst::MachRegister(base.val() + offset / 4);
299             } else if (size == 1) {
300                 Dyninst::MachRegister base = Dyninst::ppc64::cr0l;
301                 mreg = Dyninst::MachRegister(base.val() + offset);
302             } else {
303                 assert(!"bad cr register size");
304             }
305         }
306             break;
307         
308         case powerpc_regclass_fpscr:
309             assert(!"not implemented register class fpscr");
310             break;
311
312         case powerpc_regclass_spr: {
313             unsigned int minor = reg.get_minor();
314             switch (minor) {
315                 case powerpc_spr_xer: 
316                     mreg = Dyninst::ppc64::xer;
317                     break;
318                 case powerpc_spr_lr:
319                     mreg = Dyninst::ppc64::lr;
320                     break;
321                 case powerpc_spr_ctr:
322                     mreg = Dyninst::ppc64::ctr;
323                     break;
324                 case powerpc_spr_dsisr:
325                     mreg = Dyninst::ppc64::dsisr;
326                     break;
327                 case powerpc_spr_dar:
328                     mreg = Dyninst::ppc64::dar;
329                     break;
330                 case powerpc_spr_dec:
331                     mreg = Dyninst::ppc64::dec;
332                     break;
333                 default:
334                     assert(!"not implemented special register");
335             }
336         }
337             break;
338         case powerpc_regclass_tbr:
339             assert(!"not implemented regclass tbr");
340             break;
341         
342         case powerpc_regclass_msr:
343             mreg = Dyninst::ppc64::msr;
344             break;
345             
346         case powerpc_regclass_sr:
347             assert(!"not implemented regclass sr");
348             break;
349
350         case powerpc_regclass_iar:
351             mreg = Dyninst::ppc64::pc;
352             break;
353             
354         case powerpc_regclass_pvr:
355             mreg = Dyninst::ppc64::pvr;
356             break;
357         default:
358             ASSERT_always_forbid("Unexpected register major type.");
359     }
360
361     return Dyninst::Absloc(mreg);
362 }
363
364
365 ///////////////////////////////////////////////////////
366 //                                     MemoryStateAST
367 ///////////////////////////////////////////////////////
368
369 //TODO: what is Len in this case?
370
371 BaseSemantics::SValuePtr SymEvalSemantics::MemoryStateAST::readMemory(const BaseSemantics::SValuePtr &address,
372                                                                         size_t readSize) {
373     SymEvalSemantics::SValuePtr addr = SymEvalSemantics::SValue::promote(address);
374     return SymEvalSemantics::SValue::instance(Dyninst::DataflowAPI::RoseAST::create(Dyninst::DataflowAPI::ROSEOperation(Dyninst::DataflowAPI::ROSEOperation::derefOp, readSize),
375                                                                                     addr->get_expression(),
376                                                                                     Dyninst::DataflowAPI::ConstantAST::create(Dyninst::DataflowAPI::Constant(1, 1))));
377 }
378
379 BaseSemantics::SValuePtr SymEvalSemantics::MemoryStateAST::readMemory(const BaseSemantics::SValuePtr &address,
380                                                                         const BaseSemantics::SValuePtr &dflt,
381                                                                         BaseSemantics::RiscOperators */*addrOps*/,
382                                                                         BaseSemantics::RiscOperators */*valOps*/) {
383     SymEvalSemantics::SValuePtr addr = SymEvalSemantics::SValue::promote(address);
384     return SymEvalSemantics::SValue::instance(Dyninst::DataflowAPI::RoseAST::create(Dyninst::DataflowAPI::ROSEOperation(Dyninst::DataflowAPI::ROSEOperation::derefOp, dflt->get_number()),
385                                                                                     addr->get_expression(),
386                                                                                     Dyninst::DataflowAPI::ConstantAST::create(Dyninst::DataflowAPI::Constant(1, 1))));
387
388 }
389
390 void SymEvalSemantics::MemoryStateAST::writeMemory(const BaseSemantics::SValuePtr &address,
391                                                      const BaseSemantics::SValuePtr &value,
392                                                      Dyninst::DataflowAPI::Result_t &res,
393                                                      std::map<Dyninst::Absloc, Dyninst::Assignment::Ptr> &aaMap,
394                                                      size_t writeSize) {
395     std::map<Dyninst::Absloc, Dyninst::Assignment::Ptr>::iterator i = aaMap.find(Dyninst::Absloc(0));
396     SymEvalSemantics::SValuePtr addr = SymEvalSemantics::SValue::promote(address);
397
398     if (i != aaMap.end()) {
399         i->second->out().setGenerator(addr->get_expression());
400         //i->second->out().setSize(Len);
401
402         SymEvalSemantics::SValuePtr data = SymEvalSemantics::SValue::promote(value);
403         res[i->second] = data->get_expression();
404     }
405 }
406
407 void SymEvalSemantics::MemoryStateAST::writeMemory(const BaseSemantics::SValuePtr &addr,
408                                                      const BaseSemantics::SValuePtr &value,
409                                                      BaseSemantics::RiscOperators */*addrOps*/,
410                                                      BaseSemantics::RiscOperators */*valOps*/) {
411      ASSERT_always_forbid("overridden MemoryState::writeMemory() should never be called for AST, always use the non-virtual writeMemory that also takes additional parameters.");
412 }
413
414 ///////////////////////////////////////////////////////
415 //                                        RiscOperators
416 ///////////////////////////////////////////////////////
417
418 BaseSemantics::SValuePtr SymEvalSemantics::RiscOperatorsAST::and_(const BaseSemantics::SValuePtr &a_,
419                                                                const BaseSemantics::SValuePtr &b_) {
420     return createBinaryAST(Dyninst::DataflowAPI::ROSEOperation::andOp, a_, b_);
421 }
422
423 BaseSemantics::SValuePtr SymEvalSemantics::RiscOperatorsAST::or_(const BaseSemantics::SValuePtr &a_,
424                                                               const BaseSemantics::SValuePtr &b_) {
425     return createBinaryAST(Dyninst::DataflowAPI::ROSEOperation::orOp, a_, b_);
426 }
427
428 BaseSemantics::SValuePtr SymEvalSemantics::RiscOperatorsAST::xor_(const BaseSemantics::SValuePtr &a_,
429                                                                const BaseSemantics::SValuePtr &b_) {
430     return createBinaryAST(Dyninst::DataflowAPI::ROSEOperation::xorOp, a_, b_);
431 }
432
433 BaseSemantics::SValuePtr SymEvalSemantics::RiscOperatorsAST::invert(const BaseSemantics::SValuePtr &a_) {
434     return createUnaryAST(Dyninst::DataflowAPI::ROSEOperation::invertOp, a_);
435 }
436
437 BaseSemantics::SValuePtr SymEvalSemantics::RiscOperatorsAST::extract(const BaseSemantics::SValuePtr &a_, uint64_t begin,
438                                                                   uint64_t end) {
439     BaseSemantics::SValuePtr begin_ = SymEvalSemantics::SValue::instance(64, begin);
440     BaseSemantics::SValuePtr end_ = SymEvalSemantics::SValue::instance(64, end);
441
442     return createTernaryAST(Dyninst::DataflowAPI::ROSEOperation::extractOp, a_, begin_, end_, end - begin);
443 }
444
445 BaseSemantics::SValuePtr SymEvalSemantics::RiscOperatorsAST::ite(const BaseSemantics::SValuePtr &sel_,
446                                                               const BaseSemantics::SValuePtr &a_,
447                                                               const BaseSemantics::SValuePtr &b_) {
448     return createTernaryAST(Dyninst::DataflowAPI::ROSEOperation::ifOp, sel_, a_, b_);
449 }
450
451 BaseSemantics::SValuePtr SymEvalSemantics::RiscOperatorsAST::concat(const BaseSemantics::SValuePtr &a_,
452                                                                  const BaseSemantics::SValuePtr &b_) {
453     //TODO: should be able to specify number of bits to concat for each expression
454     return createBinaryAST(Dyninst::DataflowAPI::ROSEOperation::concatOp, a_, b_);
455 }
456
457 BaseSemantics::SValuePtr SymEvalSemantics::RiscOperatorsAST::leastSignificantSetBit(const BaseSemantics::SValuePtr &a_) {
458     return createUnaryAST(Dyninst::DataflowAPI::ROSEOperation::LSBSetOp, a_);
459 }
460
461 BaseSemantics::SValuePtr SymEvalSemantics::RiscOperatorsAST::mostSignificantSetBit(const BaseSemantics::SValuePtr &a_) {
462     return createUnaryAST(Dyninst::DataflowAPI::ROSEOperation::MSBSetOp, a_);
463 }
464
465 BaseSemantics::SValuePtr SymEvalSemantics::RiscOperatorsAST::rotateLeft(const BaseSemantics::SValuePtr &a_,
466                                                                      const BaseSemantics::SValuePtr &b_) {
467     return createBinaryAST(Dyninst::DataflowAPI::ROSEOperation::rotateLOp, a_, b_);
468 }
469
470 BaseSemantics::SValuePtr SymEvalSemantics::RiscOperatorsAST::rotateRight(const BaseSemantics::SValuePtr &a_,
471                                                                       const BaseSemantics::SValuePtr &b_) {
472     return createBinaryAST(Dyninst::DataflowAPI::ROSEOperation::rotateROp, a_, b_);
473 }
474
475 BaseSemantics::SValuePtr SymEvalSemantics::RiscOperatorsAST::shiftLeft(const BaseSemantics::SValuePtr &a_,
476                                                                     const BaseSemantics::SValuePtr &b_) {
477     return createBinaryAST(Dyninst::DataflowAPI::ROSEOperation::shiftLOp, a_, b_);
478 }
479
480 BaseSemantics::SValuePtr SymEvalSemantics::RiscOperatorsAST::shiftRight(const BaseSemantics::SValuePtr &a_,
481                                                                      const BaseSemantics::SValuePtr &b_) {
482     return createBinaryAST(Dyninst::DataflowAPI::ROSEOperation::shiftROp, a_, b_);
483 }
484
485 BaseSemantics::SValuePtr SymEvalSemantics::RiscOperatorsAST::shiftRightArithmetic(const BaseSemantics::SValuePtr &a_,
486                                                                                const BaseSemantics::SValuePtr &b_) {
487     return createBinaryAST(Dyninst::DataflowAPI::ROSEOperation::shiftRArithOp, a_, b_);
488 }
489
490 BaseSemantics::SValuePtr SymEvalSemantics::RiscOperatorsAST::equalToZero(const BaseSemantics::SValuePtr &a_) {
491     return createUnaryAST(Dyninst::DataflowAPI::ROSEOperation::equalToZeroOp, a_);
492 }
493
494 BaseSemantics::SValuePtr SymEvalSemantics::RiscOperatorsAST::signExtend(const BaseSemantics::SValuePtr &a_,
495                                                                      uint64_t newwidth) {
496     BaseSemantics::SValuePtr width_ = SymEvalSemantics::SValue::instance(64, newwidth);
497
498     return createBinaryAST(Dyninst::DataflowAPI::ROSEOperation::signExtendOp, a_, width_);
499 }
500
501 BaseSemantics::SValuePtr SymEvalSemantics::RiscOperatorsAST::add(const BaseSemantics::SValuePtr &a_,
502                                                               const BaseSemantics::SValuePtr &b_) {
503     return createBinaryAST(Dyninst::DataflowAPI::ROSEOperation::addOp, a_, b_);
504 }
505
506 BaseSemantics::SValuePtr SymEvalSemantics::RiscOperatorsAST::addWithCarries(const BaseSemantics::SValuePtr &a_,
507                                                                          const BaseSemantics::SValuePtr &b_,
508                                                                          const BaseSemantics::SValuePtr &c_,
509                                                                          BaseSemantics::SValuePtr &carry_out) {
510     BaseSemantics::SValuePtr aa_ = unsignedExtend(a_, a_->get_width() + 1);
511     BaseSemantics::SValuePtr bb_ = unsignedExtend(b_, b_->get_width() + 1);
512     BaseSemantics::SValuePtr sum_ = createBinaryAST(Dyninst::DataflowAPI::ROSEOperation::addOp, aa_,
513                                                     createBinaryAST(Dyninst::DataflowAPI::ROSEOperation::addOp, bb_, c_));
514
515     BaseSemantics::SValuePtr cc_ = createBinaryAST(Dyninst::DataflowAPI::ROSEOperation::xorOp, aa_,
516                                                    createBinaryAST(Dyninst::DataflowAPI::ROSEOperation::xorOp, bb_, sum_));
517     carry_out = extract(cc_, 1, a_->get_width() + 1);
518
519     return extract(sum_, 0, a_->get_width());
520 }
521
522 BaseSemantics::SValuePtr SymEvalSemantics::RiscOperatorsAST::negate(const BaseSemantics::SValuePtr &a_) {
523     return createUnaryAST(Dyninst::DataflowAPI::ROSEOperation::negateOp, a_);
524 }
525
526 BaseSemantics::SValuePtr SymEvalSemantics::RiscOperatorsAST::signedDivide(const BaseSemantics::SValuePtr &a_,
527                                                                        const BaseSemantics::SValuePtr &b_) {
528     return createBinaryAST(Dyninst::DataflowAPI::ROSEOperation::sDivOp, a_, b_);
529 }
530
531 BaseSemantics::SValuePtr SymEvalSemantics::RiscOperatorsAST::signedModulo(const BaseSemantics::SValuePtr &a_,
532                                                                        const BaseSemantics::SValuePtr &b_) {
533     return createBinaryAST(Dyninst::DataflowAPI::ROSEOperation::sModOp, a_, b_);
534 }
535
536 BaseSemantics::SValuePtr SymEvalSemantics::RiscOperatorsAST::signedMultiply(const BaseSemantics::SValuePtr &a_,
537                                                                          const BaseSemantics::SValuePtr &b_) {
538     return createBinaryAST(Dyninst::DataflowAPI::ROSEOperation::sMultOp, a_, b_);
539 }
540
541 BaseSemantics::SValuePtr SymEvalSemantics::RiscOperatorsAST::unsignedDivide(const BaseSemantics::SValuePtr &a_,
542                                                                        const BaseSemantics::SValuePtr &b_) {
543     return createBinaryAST(Dyninst::DataflowAPI::ROSEOperation::uDivOp, a_, b_);
544 }
545
546 BaseSemantics::SValuePtr SymEvalSemantics::RiscOperatorsAST::unsignedModulo(const BaseSemantics::SValuePtr &a_,
547                                                                        const BaseSemantics::SValuePtr &b_) {
548     return createBinaryAST(Dyninst::DataflowAPI::ROSEOperation::uModOp, a_, b_);
549 }
550
551 BaseSemantics::SValuePtr SymEvalSemantics::RiscOperatorsAST::unsignedMultiply(const BaseSemantics::SValuePtr &a_,
552                                                                          const BaseSemantics::SValuePtr &b_) {
553     return createBinaryAST(Dyninst::DataflowAPI::ROSEOperation::uMultOp, a_, b_);
554 }
555
556 //TODO: do we deal with byte ordering?
557 BaseSemantics::SValuePtr SymEvalSemantics::RiscOperatorsAST::readMemory(const RegisterDescriptor &/*segreg*/,
558                                                                      const BaseSemantics::SValuePtr &addr,
559                                                                      const BaseSemantics::SValuePtr &dflt,
560                                                                      const BaseSemantics::SValuePtr &/*cond*/) {
561     return currentState()->readMemory(addr, dflt, this, this);
562 }
563
564 void SymEvalSemantics::RiscOperatorsAST::writeMemory(const RegisterDescriptor &/*segreg*/,
565                                                   const BaseSemantics::SValuePtr &addr,
566                                                   const BaseSemantics::SValuePtr &data,
567                                                   const BaseSemantics::SValuePtr &/*cond*/) {
568     currentState()->writeMemory(addr, data, this, this);
569 }