#ifndef __CPUI_ADDR__
#define __CPUI_ADDR__
#include "space.hh"
class AddrSpaceManager;
class Address {
protected:
AddrSpace *base; uintb offset; public:
enum mach_extreme {
m_minimal, m_maximal };
Address(mach_extreme ex); Address(void); Address(AddrSpace *id,uintb off); Address(const Address &op2);
bool isInvalid(void) const; int4 getAddrSize(void) const; bool isBigEndian(void) const; void printRaw(ostream &s) const; int4 read(const string &s); AddrSpace *getSpace(void) const; uintb getOffset(void) const; void toPhysical(void); char getShortcut(void) const; Address &operator=(const Address &op2); bool operator==(const Address &op2) const; bool operator!=(const Address &op2) const; bool operator<(const Address &op2) const; bool operator<=(const Address &op2) const; Address operator+(int4 off) const; Address operator-(int4 off) const; friend ostream &operator<<(ostream &s,const Address &addr); bool containedBy(int4 sz,const Address &op2,int4 sz2) const; int4 justifiedContain(int4 sz,const Address &op2,int4 sz2,bool forceleft) const; int4 overlap(int4 skip,const Address &op,int4 size) const; bool isContiguous(int4 sz,const Address &loaddr,int4 losz) const; bool isConstant(void) const; void renormalize(int4 size); bool isJoin(void) const; void saveXml(ostream &s) const; void saveXml(ostream &s,int4 size) const;
static Address restoreXml(const Element *el,const AddrSpaceManager *manage);
static Address restoreXml(const Element *el,const AddrSpaceManager *manage,int4 &size);
static AddrSpace *getSpaceFromConst(const Address &addr);
};
class SeqNum {
Address pc; uintm uniq; uintm order; public:
SeqNum(void) {} SeqNum(Address::mach_extreme ex);
SeqNum(const Address &a,uintm b) : pc(a) { uniq = b; }
SeqNum(const SeqNum &op2) : pc(op2.pc) { uniq = op2.uniq; }
const Address &getAddr(void) const { return pc; }
uintm getTime(void) const { return uniq; }
uintm getOrder(void) const { return order; }
void setOrder(uintm ord) { order = ord; }
bool operator==(const SeqNum &op2) const { return (uniq == op2.uniq); }
bool operator!=(const SeqNum &op2) const { return (uniq != op2.uniq); }
bool operator<(const SeqNum &op2) const {
if (pc == op2.pc)
return (uniq < op2.uniq);
return (pc < op2.pc);
}
void saveXml(ostream &s) const;
static SeqNum restoreXml(const Element *el,const AddrSpaceManager *manage);
friend ostream &operator<<(ostream &s,const SeqNum &sq);
};
class Range {
friend class RangeList;
AddrSpace *spc; uintb first; uintb last; public:
Range(AddrSpace *s,uintb f,uintb l) {
spc = s; first = f; last = l; }
Range(void) {} AddrSpace *getSpace(void) const { return spc; } uintb getFirst(void) const { return first; } uintb getLast(void) const { return last; } Address getFirstAddr(void) const { return Address(spc,first); } Address getLastAddr(void) const { return Address(spc,last); } Address getLastAddrOpen(const AddrSpaceManager *manage) const; bool contains(const Address &addr) const;
bool operator<(const Range &op2) const {
if (spc->getIndex() != op2.spc->getIndex())
return (spc->getIndex() < op2.spc->getIndex());
return (first < op2.first); }
void printBounds(ostream &s) const; void saveXml(ostream &s) const; void restoreXml(const Element *el,const AddrSpaceManager *manage); };
class RangeList {
set<Range> tree; public:
RangeList(const RangeList &op2) { tree = op2.tree; } RangeList(void) {} void clear(void) { tree.clear(); } bool empty(void) const { return tree.empty(); } set<Range>::const_iterator begin(void) const { return tree.begin(); } set<Range>::const_iterator end(void) const { return tree.end(); } int4 numRanges(void) const { return tree.size(); } const Range *getFirstRange(void) const; const Range *getLastRange(void) const; const Range *getLastSignedRange(AddrSpace *spaceid) const; const Range *getRange(AddrSpace *spaceid,uintb offset) const; void insertRange(AddrSpace *spc,uintb first,uintb last); void removeRange(AddrSpace *spc,uintb first,uintb last); void merge(const RangeList &op2); bool inRange(const Address &addr,int4 size) const; uintb longestFit(const Address &addr,uintb maxsize) const; void printBounds(ostream &s) const; void saveXml(ostream &s) const; void restoreXml(const Element *el,const AddrSpaceManager *manage); };
extern uintb uintbmasks[];
inline Address::Address(void) {
base = (AddrSpace *)0;
}
inline Address::Address(AddrSpace *id,uintb off) {
base=id; offset=off;
}
inline Address::Address(const Address &op2) {
base = op2.base;
offset = op2.offset;
}
inline bool Address::isInvalid(void) const {
return (base == (AddrSpace *)0);
}
inline int4 Address::getAddrSize(void) const {
return base->getAddrSize();
}
inline bool Address::isBigEndian(void) const {
return base->isBigEndian();
}
inline void Address::printRaw(ostream &s) const {
if (base == (AddrSpace *)0) {
s << "invalid_addr";
return;
}
base->printRaw(s,offset);
}
inline int4 Address::read(const string &s) {
int4 sz; offset=base->read(s,sz); return sz;
}
inline AddrSpace *Address::getSpace(void) const {
return base;
}
inline uintb Address::getOffset(void) const {
return offset;
}
inline char Address::getShortcut(void) const {
return base->getShortcut();
}
inline Address &Address::operator=(const Address &op2)
{
base = op2.base;
offset = op2.offset;
return *this;
}
inline bool Address::operator==(const Address &op2) const {
return ((base==op2.base)&&(offset==op2.offset));
}
inline bool Address::operator!=(const Address &op2) const {
return !(*this==op2);
}
inline bool Address::operator<(const Address &op2) const {
if (base != op2.base) {
if (base == (AddrSpace *)0) {
return true;
}
else if (base == (AddrSpace *) ~((uintp)0)) {
return false;
}
else if (op2.base == (AddrSpace *)0) {
return false;
}
else if (op2.base == (AddrSpace *) ~((uintp)0)) {
return true;
}
return (base->getIndex() < op2.base->getIndex());
}
if (offset != op2.offset) return (offset < op2.offset);
return false;
}
inline bool Address::operator<=(const Address &op2) const {
if (base != op2.base) {
if (base == (AddrSpace *)0) {
return true;
}
else if (base == (AddrSpace *) ~((uintp)0)) {
return false;
}
else if (op2.base == (AddrSpace *)0) {
return false;
}
else if (op2.base == (AddrSpace *) ~((uintp)0)) {
return true;
}
return (base->getIndex() < op2.base->getIndex());
}
if (offset != op2.offset) return (offset < op2.offset);
return true;
}
inline Address Address::operator+(int4 off) const {
return Address(base,base->wrapOffset(offset+off));
}
inline Address Address::operator-(int4 off) const {
return Address(base,base->wrapOffset(offset-off));
}
inline bool Address::isConstant(void) const {
return (base->getType() == IPTR_CONSTANT);
}
inline bool Address::isJoin(void) const {
return (base->getType() == IPTR_JOIN);
}
inline void Address::saveXml(ostream &s) const {
s << "<addr";
if (base!=(AddrSpace *)0)
base->saveXmlAttributes(s,offset);
s << "/>";
}
inline void Address::saveXml(ostream &s,int4 size) const {
s << "<addr";
if (base!=(AddrSpace *)0)
base->saveXmlAttributes(s,offset,size);
s << "/>";
}
inline AddrSpace *Address::getSpaceFromConst(const Address &addr) {
return (AddrSpace *)(uintp)addr.offset;
}
inline bool Range::contains(const Address &addr) const {
if (spc != addr.getSpace()) return false;
if (first > addr.getOffset()) return false;
if (last < addr.getOffset()) return false;
return true;
}
inline uintb calc_mask(int4 size) { return uintbmasks[(size<8)? size : 8]; }
inline uintb pcode_right(uintb val,int4 sa) {
if (sa >= 8*sizeof(uintb)) return 0;
return val >> sa;
}
inline uintb pcode_left(uintb val,int4 sa) {
if (sa >= 8*sizeof(uintb)) return 0;
return val << sa;
}
inline uintb minimalmask(uintb val)
{
if (val > 0xffffffff)
return ~((uintb)0);
if (val > 0xffff)
return 0xffffffff;
if (val > 0xff)
return 0xffff;
return 0xff;
}
extern bool signbit_negative(uintb val,int4 size); extern uintb calc_mask(int4 size); extern uintb uintb_negate(uintb in,int4 size); extern uintb sign_extend(uintb in,int4 sizein,int4 sizeout);
extern void sign_extend(intb &val,int4 bit); extern void zero_extend(intb &val,int4 bit); extern void byte_swap(intb &val,int4 size);
extern uintb byte_swap(uintb val,int4 size); extern int4 leastsigbit_set(uintb val); extern int4 mostsigbit_set(uintb val); extern int4 popcount(uintb val); extern int4 count_leading_zeros(uintb val);
extern uintb coveringmask(uintb val); extern int4 bit_transitions(uintb val,int4 sz);
extern void mult64to128(uint8 *res,uint8 x,uint8 y);
extern void unsignedSubtract128(uint8 *a,uint8 *b);
extern int4 unsignedCompare128(uint8 *a,uint8 *b);
extern int4 power2Divide(int4 n,uint8 divisor,uint8 &q,uint8 &r);
#endif