CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
550 lines
31 KiB
C++
550 lines
31 KiB
C++
#ifndef Rose_ConcreteSemantics2_H
|
|
#define Rose_ConcreteSemantics2_H
|
|
|
|
#ifndef __STDC_FORMAT_MACROS
|
|
#define __STDC_FORMAT_MACROS
|
|
#endif
|
|
|
|
#include <iosfwd>
|
|
#include <stddef.h>
|
|
#include <inttypes.h>
|
|
|
|
#include "../integerOps.h"
|
|
#include "BaseSemantics2.h"
|
|
#include "MemoryMap.h"
|
|
#include "RegisterStateGeneric.h"
|
|
#include "../util/BitVector.h"
|
|
|
|
namespace rose {
|
|
namespace BinaryAnalysis { // documented elsewhere
|
|
namespace InstructionSemantics2 { // documented elsewhere
|
|
|
|
/** A concrete semantic domain.
|
|
*
|
|
* Semantics in a concrete domain, where all values are actual known bits. Since the symbolic domain does constant folding,
|
|
* it also can be used as a concrete domain, although using ConcreteSemantics is probably somewhat faster. */
|
|
namespace ConcreteSemantics {
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Value type
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
/** Smart-ownership pointer to a concrete semantic value. See @ref heap_object_shared_ownership. */
|
|
typedef Sawyer::SharedPointer<class SValue> SValuePtr;
|
|
|
|
/** Formatter for symbolic values. */
|
|
typedef BaseSemantics::Formatter Formatter; // we might extend this in the future
|
|
|
|
/** Type of values manipulated by the concrete domain.
|
|
*
|
|
* Values of type type are used whenever a value needs to be stored, such as memory addresses, the values stored at those
|
|
* addresses, the values stored in registers, the operands for RISC operations, and the results of those operations. Each
|
|
* value has a known size and known bits. All RISC operations on these values will produce a new known value. This type is
|
|
* not capable of storing an undefined value, and any attempt to create an undefined value will create a value with all bits
|
|
* cleared instead. */
|
|
class SValue : public BaseSemantics::SValue {
|
|
protected:
|
|
Sawyer::Container::BitVector bits_;
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Real constructors
|
|
protected:
|
|
explicit SValue(size_t nbits) : BaseSemantics::SValue(nbits), bits_(nbits) { }
|
|
|
|
SValue(size_t nbits, uint64_t number) : BaseSemantics::SValue(nbits) {
|
|
bits_ = Sawyer::Container::BitVector(nbits);
|
|
bits_.fromInteger(number);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Static allocating constructors
|
|
public:
|
|
/** Instantiate a new prototypical value. Prototypical values are only used for their virtual constructors. */
|
|
static SValuePtr instance() {
|
|
return SValuePtr(new SValue(1));
|
|
}
|
|
|
|
/** Instantiate a new undefined value of specified width.
|
|
*
|
|
* This semantic domain has no representation for an undefined values--all values are defined. Therefore any attempt to
|
|
* create an undefined value will result in all bits being set to zero instead. */
|
|
static SValuePtr instance(size_t nbits) {
|
|
return SValuePtr(new SValue(nbits));
|
|
}
|
|
|
|
/** Instantiate a new concrete value. */
|
|
static SValuePtr instance(size_t nbits, uint64_t value) {
|
|
return SValuePtr(new SValue(nbits, value));
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Virtual allocating constructors
|
|
public:
|
|
virtual BaseSemantics::SValuePtr undefined_(size_t nbits) const {
|
|
return instance(nbits);
|
|
}
|
|
|
|
virtual BaseSemantics::SValuePtr unspecified_(size_t nbits) const {
|
|
return instance(nbits);
|
|
}
|
|
|
|
virtual BaseSemantics::SValuePtr bottom_(size_t nbits) const {
|
|
return instance(nbits);
|
|
}
|
|
|
|
virtual BaseSemantics::SValuePtr number_(size_t nbits, uint64_t value) const {
|
|
return instance(nbits, value);
|
|
}
|
|
|
|
virtual BaseSemantics::SValuePtr boolean_(bool value) const {
|
|
return instance(1, value ? 1 : 0);
|
|
}
|
|
|
|
virtual BaseSemantics::SValuePtr copy(size_t new_width = 0) const {
|
|
SValuePtr retval(new SValue(*this));
|
|
if (new_width != 0 && new_width != retval->get_width())
|
|
retval->set_width(new_width);
|
|
return retval;
|
|
}
|
|
|
|
virtual Sawyer::Optional <BaseSemantics::SValuePtr>
|
|
createOptionalMerge(const BaseSemantics::SValuePtr &other, const BaseSemantics::MergerPtr &,
|
|
SMTSolver *) const;
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Dynamic pointer casts
|
|
public:
|
|
/** Promote a base value to a SymbolicSemantics value. The value @p v must have a SymbolicSemantics::SValue dynamic type. */
|
|
static SValuePtr promote(const BaseSemantics::SValuePtr &v) { // hot
|
|
SValuePtr retval = v.dynamicCast<SValue>();
|
|
ASSERT_not_null(retval);
|
|
return retval;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Override virtual methods...
|
|
public:
|
|
virtual bool may_equal(const BaseSemantics::SValuePtr &other, SMTSolver *solver = NULL) const;
|
|
|
|
virtual bool must_equal(const BaseSemantics::SValuePtr &other, SMTSolver *solver = NULL) const;
|
|
|
|
virtual void set_width(size_t nbits);
|
|
|
|
virtual bool isBottom() const {
|
|
return false;
|
|
}
|
|
|
|
virtual bool is_number() const {
|
|
return true;
|
|
}
|
|
|
|
virtual uint64_t get_number() const;
|
|
|
|
virtual void print(std::ostream &, BaseSemantics::Formatter &) const;
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Additional methods first declared in this class...
|
|
public:
|
|
/** Returns the bit vector storing the concrete value.
|
|
*
|
|
* @{ */
|
|
virtual const Sawyer::Container::BitVector &bits() const { return bits_; }
|
|
|
|
virtual void bits(const Sawyer::Container::BitVector &);
|
|
/** @} */
|
|
};
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Register State
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
typedef BaseSemantics::RegisterStateGeneric RegisterState;
|
|
typedef BaseSemantics::RegisterStateGenericPtr RegisterStatePtr;
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Memory State
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
/** Shared-ownership pointer to a concrete memory state. See @ref heap_object_shared_ownership. */
|
|
typedef dyncompat::shared_ptr<class MemoryState> MemoryStatePtr;
|
|
|
|
/** Byte-addressable memory.
|
|
*
|
|
* This class represents an entire state of memory via MemoryMap, allocating new memory in units of pages (the size of a page
|
|
* is configurable. */
|
|
class MemoryState : public BaseSemantics::MemoryState {
|
|
MemoryMap map_;
|
|
rose_addr_t pageSize_;
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Real constructors
|
|
protected:
|
|
explicit MemoryState(const BaseSemantics::SValuePtr &addrProtoval,
|
|
const BaseSemantics::SValuePtr &valProtoval)
|
|
: BaseSemantics::MemoryState(addrProtoval, valProtoval), pageSize_(4096) {
|
|
(void) SValue::promote(addrProtoval); // for its checking side effects
|
|
(void) SValue::promote(valProtoval);
|
|
}
|
|
|
|
MemoryState(const MemoryState &other)
|
|
: BaseSemantics::MemoryState(other), map_(other.map_), pageSize_(other.pageSize_) {
|
|
DYN_FOREACH(MemoryMap::Segment & segment, map_.values())
|
|
segment.buffer()->copyOnWrite(true);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Static allocating constructors
|
|
public:
|
|
/** Instantiates a new memory state having specified prototypical value.
|
|
*
|
|
* The @p addrProtoval and @p valProtoval must both be of ConcreteSemantics::SValue type or derived classes. */
|
|
static MemoryStatePtr instance(const BaseSemantics::SValuePtr &addrProtoval,
|
|
const BaseSemantics::SValuePtr &valProtoval) {
|
|
return MemoryStatePtr(new MemoryState(addrProtoval, valProtoval));
|
|
}
|
|
|
|
/** Instantiates a new deep copy of an existing state.
|
|
*
|
|
* For efficiency purposes, the data buffers are not copied immediately but rather marked as copy-on-write. However, the
|
|
* newly constructed memory map will have its own segments, which hold the segment names, access permissions, etc. */
|
|
static MemoryStatePtr instance(const MemoryStatePtr &other) {
|
|
return MemoryStatePtr(new MemoryState(*other));
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Virtual constructors
|
|
public:
|
|
/** Virtual constructor.
|
|
*
|
|
* Creates a memory state having specified prototypical value, which should be of type ConcreteSemantics::SValue or
|
|
* subclasses. */
|
|
virtual BaseSemantics::MemoryStatePtr create(const BaseSemantics::SValuePtr &addrProtoval,
|
|
const BaseSemantics::SValuePtr &valProtoval) const
|
|
|
|
{
|
|
return instance(addrProtoval, valProtoval);
|
|
}
|
|
|
|
/** Virtual copy constructor.
|
|
*
|
|
* Creates a new deep copy of this memory state. For efficiency purposes, the data buffers are not copied immediately but
|
|
* rather marked as copy-on-write. However, the newly constructed memory map will have its own segments, which hold the
|
|
* segment names, access permissions, etc. */
|
|
virtual BaseSemantics::MemoryStatePtr clone() const {
|
|
return MemoryStatePtr(new MemoryState(*this));
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Dynamic pointer casts
|
|
public:
|
|
/** Recasts a base pointer to a concrete memory state. This is a checked cast that will fail if the specified pointer does
|
|
* not have a run-time type that is a ConcreteSemantics::MemoryState or subclass thereof. */
|
|
static MemoryStatePtr promote(const BaseSemantics::MemoryStatePtr &x) {
|
|
MemoryStatePtr retval = dyncompat::dynamic_pointer_cast<MemoryState>(x);
|
|
ASSERT_not_null(retval);
|
|
return retval;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Methods we inherited
|
|
public:
|
|
virtual void clear() {
|
|
map_.clear();
|
|
}
|
|
|
|
virtual void print(std::ostream &, Formatter &) const;
|
|
|
|
virtual BaseSemantics::SValuePtr readMemory(const BaseSemantics::SValuePtr &addr,
|
|
const BaseSemantics::SValuePtr &dflt,
|
|
BaseSemantics::RiscOperators *addrOps,
|
|
BaseSemantics::RiscOperators *valOps);
|
|
|
|
virtual void writeMemory(const BaseSemantics::SValuePtr &addr,
|
|
const BaseSemantics::SValuePtr &value,
|
|
BaseSemantics::RiscOperators *addrOps,
|
|
BaseSemantics::RiscOperators *valOps);
|
|
|
|
virtual bool merge(const BaseSemantics::MemoryStatePtr &other,
|
|
BaseSemantics::RiscOperators *addrOps,
|
|
BaseSemantics::RiscOperators *valOps);
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Methods first declared in this class
|
|
public:
|
|
/** Returns the memory map. */
|
|
const MemoryMap &memoryMap() const { return map_; }
|
|
|
|
/** Set memory map.
|
|
*
|
|
* If the specified map's areas not not in units of pages then padding segments will be added to this memory state. The
|
|
* padding segments will either have the accessibility specified by @p padAccess, or will have the same accessibility as
|
|
* the memory region being padded. All padding segments will be named "padding". */
|
|
void memoryMap(const MemoryMap &, Sawyer::Optional<unsigned> padAccess = Sawyer::Nothing());
|
|
|
|
/** Size of each page of memory.
|
|
*
|
|
* Memory is allocated in units of the page size and aligned on page-size boundaries. The page size cannot be changed
|
|
* once the map contains data.
|
|
*
|
|
* @{ */
|
|
rose_addr_t pageSize() const { return pageSize_; }
|
|
|
|
void pageSize(rose_addr_t nBytes);
|
|
/** @} */
|
|
|
|
/** Allocate a page of memory.
|
|
*
|
|
* The specified address will be contained in the page, which is aligned on a page boundary. Do not call this if the page
|
|
* is already allocated unless: it will replace the allocated page with a new one containing all zeros. */
|
|
void allocatePage(rose_addr_t va);
|
|
|
|
};
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Complete semantic state
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
typedef BaseSemantics::State State;
|
|
typedef BaseSemantics::StatePtr StatePtr;
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// RISC operators
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
/** Shared-ownership pointer to concrete RISC operations. See @ref heap_object_shared_ownership. */
|
|
typedef dyncompat::shared_ptr<class RiscOperators> RiscOperatorsPtr;
|
|
|
|
/** Defines RISC operators for the ConcreteSemantics domain.
|
|
*
|
|
* These RISC operators depend on functionality introduced into the SValue class hierarchy at the ConcreteSemantics::SValue
|
|
* level. Therefore, the prototypical value supplied to the constructor or present in the supplied state object must have a
|
|
* dynamic type which is a ConcreteSemantics::SValue (or subclass).
|
|
*
|
|
* Each RISC operator should return a newly allocated semantic value rather than trying to re-use an existing one. This will
|
|
* allow the caller to change the value stored there without affecting any of the input arguments. For example, a no-op that
|
|
* returns its argument should be implemented like this:
|
|
*
|
|
* @code
|
|
* BaseSemantics::SValuePtr noop(const BaseSemantics::SValuePtr &arg) {
|
|
* return arg->copy(); //correct
|
|
* return arg; //incorrect
|
|
* }
|
|
* @endcode
|
|
*/
|
|
class RiscOperators : public BaseSemantics::RiscOperators {
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Real constructors
|
|
protected:
|
|
RiscOperators(const BaseSemantics::SValuePtr &protoval, SMTSolver *solver)
|
|
: BaseSemantics::RiscOperators(protoval, solver) {
|
|
name("Concrete");
|
|
(void) SValue::promote(protoval); // make sure its dynamic type is a ConcreteSemantics::SValue
|
|
}
|
|
|
|
RiscOperators(const BaseSemantics::StatePtr &state, SMTSolver *solver)
|
|
: BaseSemantics::RiscOperators(state, solver) {
|
|
name("Concrete");
|
|
(void) SValue::promote(
|
|
state->protoval()); // values must have ConcreteSemantics::SValue dynamic type
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Static allocating constructors
|
|
public:
|
|
/** Instantiates a new RiscOperators object and configures it to use semantic values and states that are defaults for
|
|
* ConcreteSemantics. */
|
|
static RiscOperatorsPtr instance(const RegisterDictionary *regdict, SMTSolver *solver = NULL) {
|
|
BaseSemantics::SValuePtr protoval = SValue::instance();
|
|
BaseSemantics::RegisterStatePtr registers = RegisterState::instance(protoval, regdict);
|
|
BaseSemantics::MemoryStatePtr memory = MemoryState::instance(protoval, protoval);
|
|
BaseSemantics::StatePtr state = State::instance(registers, memory);
|
|
return RiscOperatorsPtr(new RiscOperators(state, solver));
|
|
}
|
|
|
|
/** Instantiates a new RiscOperators object with specified prototypical values. An SMT solver may be specified as the
|
|
* second argument because the base class expects one, but it is not used for concrete semantics. See @ref solver for
|
|
* details. */
|
|
static RiscOperatorsPtr instance(const BaseSemantics::SValuePtr &protoval,
|
|
SMTSolver *solver = NULL) {
|
|
return RiscOperatorsPtr(new RiscOperators(protoval, solver));
|
|
}
|
|
|
|
/** Instantiates a new RiscOperators object with specified state. An SMT solver may be specified as the second argument
|
|
* because the base class expects one, but it is not used for concrete semantics. See @ref solver for details. */
|
|
static RiscOperatorsPtr instance(const BaseSemantics::StatePtr &state, SMTSolver *solver = NULL) {
|
|
return RiscOperatorsPtr(new RiscOperators(state, solver));
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Virtual constructors
|
|
public:
|
|
virtual BaseSemantics::RiscOperatorsPtr create(const BaseSemantics::SValuePtr &protoval,
|
|
SMTSolver *solver = NULL) const {
|
|
return instance(protoval, solver);
|
|
}
|
|
|
|
virtual BaseSemantics::RiscOperatorsPtr create(const BaseSemantics::StatePtr &state,
|
|
SMTSolver *solver = NULL) const {
|
|
return instance(state, solver);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Dynamic pointer casts
|
|
public:
|
|
/** Run-time promotion of a base RiscOperators pointer to concrete operators. This is a checked conversion--it
|
|
* will fail if @p x does not point to a ConcreteSemantics::RiscOperators object. */
|
|
static RiscOperatorsPtr promote(const BaseSemantics::RiscOperatorsPtr &x) {
|
|
RiscOperatorsPtr retval = dyncompat::dynamic_pointer_cast<RiscOperators>(x);
|
|
ASSERT_not_null(retval);
|
|
return retval;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// New methods for constructing values, so we don't have to write so many SValue::promote calls in the RiscOperators
|
|
// implementations.
|
|
protected:
|
|
SValuePtr svalue_number(size_t nbits, uint64_t value) {
|
|
return SValue::promote(number_(nbits, value));
|
|
}
|
|
|
|
SValuePtr svalue_number(const Sawyer::Container::BitVector &);
|
|
|
|
SValuePtr svalue_boolean(bool b) {
|
|
return SValue::promote(boolean_(b));
|
|
}
|
|
|
|
SValuePtr svalue_zero(size_t nbits) {
|
|
return SValue::promote(number_(nbits, 0));
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Override methods from base class. These are the RISC operators that are invoked by a Dispatcher.
|
|
public:
|
|
virtual void interrupt(int majr, int minr);
|
|
|
|
virtual BaseSemantics::SValuePtr and_(const BaseSemantics::SValuePtr &a_,
|
|
const BaseSemantics::SValuePtr &b_);
|
|
|
|
virtual BaseSemantics::SValuePtr or_(const BaseSemantics::SValuePtr &a_,
|
|
const BaseSemantics::SValuePtr &b_);
|
|
|
|
virtual BaseSemantics::SValuePtr xor_(const BaseSemantics::SValuePtr &a_,
|
|
const BaseSemantics::SValuePtr &b_);
|
|
|
|
virtual BaseSemantics::SValuePtr invert(const BaseSemantics::SValuePtr &a_);
|
|
|
|
virtual BaseSemantics::SValuePtr extract(const BaseSemantics::SValuePtr &a_,
|
|
size_t begin_bit, size_t end_bit);
|
|
|
|
virtual BaseSemantics::SValuePtr concat(const BaseSemantics::SValuePtr &a_,
|
|
const BaseSemantics::SValuePtr &b_);
|
|
|
|
virtual BaseSemantics::SValuePtr leastSignificantSetBit(const BaseSemantics::SValuePtr &a_);
|
|
|
|
virtual BaseSemantics::SValuePtr mostSignificantSetBit(const BaseSemantics::SValuePtr &a_);
|
|
|
|
virtual BaseSemantics::SValuePtr rotateLeft(const BaseSemantics::SValuePtr &a_,
|
|
const BaseSemantics::SValuePtr &sa_);
|
|
|
|
virtual BaseSemantics::SValuePtr rotateRight(const BaseSemantics::SValuePtr &a_,
|
|
const BaseSemantics::SValuePtr &sa_);
|
|
|
|
virtual BaseSemantics::SValuePtr shiftLeft(const BaseSemantics::SValuePtr &a_,
|
|
const BaseSemantics::SValuePtr &sa_);
|
|
|
|
virtual BaseSemantics::SValuePtr shiftRight(const BaseSemantics::SValuePtr &a_,
|
|
const BaseSemantics::SValuePtr &sa_);
|
|
|
|
virtual BaseSemantics::SValuePtr shiftRightArithmetic(const BaseSemantics::SValuePtr &a_,
|
|
const BaseSemantics::SValuePtr &sa_);
|
|
|
|
virtual BaseSemantics::SValuePtr equalToZero(const BaseSemantics::SValuePtr &a_);
|
|
|
|
virtual BaseSemantics::SValuePtr ite(const BaseSemantics::SValuePtr &sel_,
|
|
const BaseSemantics::SValuePtr &a_,
|
|
const BaseSemantics::SValuePtr &b_);
|
|
|
|
virtual BaseSemantics::SValuePtr unsignedExtend(const BaseSemantics::SValuePtr &a_,
|
|
size_t new_width);
|
|
|
|
virtual BaseSemantics::SValuePtr signExtend(const BaseSemantics::SValuePtr &a_, size_t new_width);
|
|
|
|
virtual BaseSemantics::SValuePtr add(const BaseSemantics::SValuePtr &a_,
|
|
const BaseSemantics::SValuePtr &b_);
|
|
|
|
virtual BaseSemantics::SValuePtr addWithCarries(const BaseSemantics::SValuePtr &a_,
|
|
const BaseSemantics::SValuePtr &b_,
|
|
const BaseSemantics::SValuePtr &c_,
|
|
BaseSemantics::SValuePtr &carry_out/*out*/);
|
|
|
|
virtual BaseSemantics::SValuePtr negate(const BaseSemantics::SValuePtr &a_);
|
|
|
|
virtual BaseSemantics::SValuePtr signedDivide(const BaseSemantics::SValuePtr &a_,
|
|
const BaseSemantics::SValuePtr &b_);
|
|
|
|
virtual BaseSemantics::SValuePtr signedModulo(const BaseSemantics::SValuePtr &a_,
|
|
const BaseSemantics::SValuePtr &b_);
|
|
|
|
virtual BaseSemantics::SValuePtr signedMultiply(const BaseSemantics::SValuePtr &a_,
|
|
const BaseSemantics::SValuePtr &b_);
|
|
|
|
virtual BaseSemantics::SValuePtr unsignedDivide(const BaseSemantics::SValuePtr &a_,
|
|
const BaseSemantics::SValuePtr &b_);
|
|
|
|
virtual BaseSemantics::SValuePtr unsignedModulo(const BaseSemantics::SValuePtr &a_,
|
|
const BaseSemantics::SValuePtr &b_);
|
|
|
|
virtual BaseSemantics::SValuePtr unsignedMultiply(const BaseSemantics::SValuePtr &a_,
|
|
const BaseSemantics::SValuePtr &b_);
|
|
|
|
virtual BaseSemantics::SValuePtr fpFromInteger(const BaseSemantics::SValuePtr &intValue,
|
|
SgAsmFloatType *);
|
|
|
|
virtual BaseSemantics::SValuePtr fpToInteger(const BaseSemantics::SValuePtr &fpValue,
|
|
SgAsmFloatType *fpType,
|
|
const BaseSemantics::SValuePtr &dflt);
|
|
|
|
virtual BaseSemantics::SValuePtr fpAdd(const BaseSemantics::SValuePtr &a,
|
|
const BaseSemantics::SValuePtr &b,
|
|
SgAsmFloatType *);
|
|
|
|
virtual BaseSemantics::SValuePtr fpSubtract(const BaseSemantics::SValuePtr &a,
|
|
const BaseSemantics::SValuePtr &b,
|
|
SgAsmFloatType *);
|
|
|
|
virtual BaseSemantics::SValuePtr fpMultiply(const BaseSemantics::SValuePtr &a,
|
|
const BaseSemantics::SValuePtr &b,
|
|
SgAsmFloatType *);
|
|
|
|
virtual BaseSemantics::SValuePtr fpRoundTowardZero(const BaseSemantics::SValuePtr &a,
|
|
SgAsmFloatType *);
|
|
|
|
virtual BaseSemantics::SValuePtr readMemory(const RegisterDescriptor &segreg,
|
|
const BaseSemantics::SValuePtr &addr,
|
|
const BaseSemantics::SValuePtr &dflt,
|
|
const BaseSemantics::SValuePtr &cond);
|
|
|
|
virtual void writeMemory(const RegisterDescriptor &segreg,
|
|
const BaseSemantics::SValuePtr &addr,
|
|
const BaseSemantics::SValuePtr &data,
|
|
const BaseSemantics::SValuePtr &cond);
|
|
|
|
protected:
|
|
// Convert expression to double
|
|
double exprToDouble(const BaseSemantics::SValuePtr &expr, SgAsmFloatType *);
|
|
|
|
// Convert double to expression
|
|
BaseSemantics::SValuePtr doubleToExpr(double d, SgAsmFloatType *);
|
|
};
|
|
|
|
} // namespace
|
|
} // namespace
|
|
} // namespace
|
|
} // namespace
|
|
|
|
#endif
|