arch-power.C
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #include "common/h/Types.h"
00032 #include "common/h/arch-power.h"
00033 using namespace NS_power;
00034
00035 #if defined(os_vxworks)
00036 #include "common/h/wtxKludges.h"
00037 #endif
00038
00039 unsigned int NS_power::swapBytesIfNeeded(unsigned int i)
00040 {
00041 static int one = 0x1;
00042
00043 if ( *((unsigned char *)&one) )
00044 return instruction::swapBytes( *((instructUnion *)&i) ).raw;
00045
00046 return i;
00047 }
00048
00049 int instruction::signExtend(unsigned int i, unsigned int pos)
00050 {
00051 int ret;
00052 if (((i >> (--pos)) & 0x1) == 0x1) {
00053 ret = i | (~0 << pos);
00054 } else {
00055 ret = i & ~(~0 << pos);
00056 }
00057
00058 return ret;
00059 }
00060
00061 instructUnion &instruction::swapBytes(instructUnion &i)
00062 {
00063 i.byte[0] = i.byte[0] ^ i.byte[3];
00064 i.byte[3] = i.byte[0] ^ i.byte[3];
00065 i.byte[0] = i.byte[0] ^ i.byte[3];
00066
00067 i.byte[1] = i.byte[1] ^ i.byte[2];
00068 i.byte[2] = i.byte[1] ^ i.byte[2];
00069 i.byte[1] = i.byte[1] ^ i.byte[2];
00070
00071 return i;
00072 }
00073
00074 instruction *instruction::copy() const {
00075 return new instruction(*this);
00076 }
00077
00078 Address instruction::getTarget(Address addr) const {
00079 #if defined(os_vxworks)
00080 Address ret;
00081
00082 if (relocationTarget(addr, &ret))
00083 return ret;
00084 #endif
00085
00086 if (isUncondBranch() || isCondBranch()) {
00087 return getBranchOffset() + addr;
00088 }
00089 else if (isInsnType(Bmask, BAAmatch))
00090 return (IFORM_LI(*this) << 2);
00091 else if (isInsnType(Bmask, BCAAmatch))
00092 return (BFORM_BD(*this) << 2);
00093
00094 return 0;
00095 }
00096
00097
00098 void instruction::setBranchOffset(Address newOffset) {
00099 if (isUncondBranch()) {
00100 assert(ABS((int) newOffset) < MAX_BRANCH);
00101 IFORM_LI_SET(*this, newOffset >> 2);
00102 }
00103 else if (isCondBranch()) {
00104 assert(ABS(newOffset) < MAX_CBRANCH);
00105 BFORM_BD_SET(*this, newOffset >> 2);
00106 }
00107 else {
00108 assert(0);
00109 }
00110 }
00111
00112
00113 bool instruction::isCall() const
00114 {
00115 #define CALLmatch 0x48000001
00116
00117
00118
00119
00120 return(isInsnType(OPmask | AALKmask, CALLmatch));
00121 }
00122
00123 void instruction::setInstruction(codeBuf_t *ptr, Address) {
00124
00125
00126 instructUnion *insnPtr = (instructUnion *)ptr;
00127
00128 #if defined(endian_mismatch)
00129
00130 insn_.raw = swapBytesIfNeeded((*insnPtr).raw);
00131 #else
00132 insn_.raw = (*insnPtr).raw;
00133 #endif
00134 }
00135 void instruction::setInstruction(unsigned char *ptr, Address) {
00136
00137 instructUnion *insnPtr = (instructUnion *)ptr;
00138 insn_ = *insnPtr;
00139 }
00140
00141 bool instruction::isUncondBranch() const {
00142 return isInsnType(Bmask, Bmatch);
00143 }
00144
00145 bool instruction::isCondBranch() const {
00146 return isInsnType(Bmask, BCmatch);
00147 }
00148
00149 unsigned instruction::jumpSize(Address from, Address to, unsigned addr_width) {
00150 Address disp = ABS((long)(to - from));
00151 return jumpSize(disp, addr_width);
00152 }
00153
00154
00155 unsigned instruction::jumpSize(Address disp, unsigned addr_width) {
00156 if (ABS(disp) >= MAX_BRANCH) {
00157 return maxInterFunctionJumpSize(addr_width);
00158 }
00159 return instruction::size();
00160 }
00161
00162 unsigned instruction::maxJumpSize(unsigned addr_width) {
00163
00164
00165
00166 if (addr_width == 4)
00167 return 30*instruction::size();
00168 else
00169 return 7*instruction::size();
00170 }
00171
00172 unsigned instruction::maxInterFunctionJumpSize(unsigned addr_width) {
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187 if (addr_width == 8)
00188 return 7*instruction::size();
00189 else
00190 return 4*instruction::size();
00191 }
00192
00193 unsigned instruction::spaceToRelocate() const {
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203 if (isThunk()) {
00204
00205 return 30*instruction::size();
00206 }
00207 else if (isCondBranch()) {
00208
00209 if ((BFORM_BO(*this) & BALWAYSmask) != BALWAYScond) {
00210 return 3*instruction::size();
00211 }
00212 }
00213 if (isUncondBranch()) {
00214
00215
00216
00217
00218 return 9*instruction::size();
00219 }
00220 return instruction::size();
00221 }
00222
00223 bool instruction::getUsedRegs(pdvector<int> &) {
00224 return false;
00225 }
00226
00227
00228
00229
00230
00231
00232
00233 bool instruction::isThunk() const {
00234 switch (BFORM_OP(*this)) {
00235 case Bop:
00236
00237 break;
00238 case BCop:
00239
00240 if (!(BFORM_BO(*this) & 0x14))
00241 return false;
00242 break;
00243 default:
00244 return false;
00245 break;
00246 }
00247
00248
00249
00250
00251
00252 if (BFORM_BD(*this) != 1) return false;
00253
00254
00255 if (!BFORM_LK(*this)) return false;
00256
00257
00258 if (BFORM_AA(*this)) return false;
00259
00260 return true;
00261 }
00262
00263 Address instruction::getBranchOffset() const {
00264 if (isUncondBranch()) {
00265 return (IFORM_LI(*this) << 2);
00266 }
00267 else if (isCondBranch()) {
00268 return (BFORM_BD(*this) << 2);
00269 }
00270 return 0;
00271
00272 }
00273
00274 unsigned instruction::opcode() const {
00275 return MDFORM_OP(*this);
00276 }