Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | File Members

/users/u3/mtikir/PMaCInstrumentor_v1601/src/Instruction.C

Go to the documentation of this file.
00001 #include <Instruction.h>
00002 #include <SectHeader.h>
00003 #include <SymbolTable.h>
00004 #include <DemangleWrapper.h>
00005 #include <LoaderSection.h>
00006 #include <RawSection.h>
00007 #include <Iterator.h>
00008 #include <Function.h>
00009 #include <XCoffFile.h>
00010 #include <BinaryFile.h>
00011 
00014 Operand Operand::IntegerOperand0 = IntegerOperand(0);
00015 
00016 Operand* Operand::GPRegisterOperands = initGPRegisterOperands();
00017 
00018 Operand* Operand::initGPRegisterOperands(){
00019     Operand* ret = new Operand[NUM_OF_GPR_REGS];
00020     for(uint32_t i=0;i<NUM_OF_GPR_REGS;i++)
00021         ret[i] = GPRegisterOperand(i);
00022     return ret;
00023 }
00024 
00025 BitSet<>* Instruction::memoryOperationXops = Instruction::initMemoryOperationXops();
00026 
00027 BitSet<>* Instruction::initMemoryOperationXops(){
00028     BitSet<>* ret = new BitSet<>(INVALID_XOP);
00029     uint32_t xops[] = { xcode_Lwarx,xcode_Ldx,xcode_Lwzx,xcode_Ldux,xcode_Lwzux,xcode_Ldarx,
00030                         xcode_Lbzx,xcode_Lbzux,xcode_Stdx,xcode_Stwcxc,xcode_Stwx,xcode_Stdux,
00031                         xcode_Stwux,xcode_Stdcxc,xcode_Stbx,xcode_Stbux,xcode_Lhzx,xcode_Lhzux,
00032                         xcode_Lwax,xcode_Lhax,xcode_Lwaux,xcode_Lhaux,xcode_Sthx,xcode_Sthux,
00033                         xcode_Lswx,xcode_Lwbrx,xcode_Lfsx,xcode_Lfsux,xcode_Lswi,xcode_Lfdx,
00034                         xcode_Lfdux,xcode_Stswx,xcode_Stwbrx,xcode_Stfsx,xcode_Stfsux,xcode_Stswi,
00035                         xcode_Stfdx,xcode_Stfdux,xcode_Lhbrx,xcode_Sthbrx,xcode_Stfiwx,
00036                         xcode_LscbxC,
00037                         INVALID_XOP };
00038 
00039     for(uint32_t i=0;xops[i] != INVALID_XOP;i++)
00040         ret->insert(xops[i]);
00041 
00042     return ret;
00043 }
00044 
00045 bool Instruction::isCondBranch() { 
00046     if(!ppci.lk.lk &&
00047        IS_BC(ppci) && 
00048        !BRANCH_ALWAYS(ppci.b.bo))
00049        return true;
00050     return false; 
00051 }
00052 
00053 bool Instruction::isJump() { 
00054     if(!ppci.lk.lk){
00055         if(IS_B(ppci))
00056             return true;
00057         if(IS_BC(ppci) && 
00058            BRANCH_ALWAYS(ppci.b.bo))
00059             return true;
00060     }
00061     return false; 
00062 }
00063 
00064 bool Instruction::isReturn() { 
00065     if(!ppci.lk.lk){
00066         if(IS_BCLR(ppci) && 
00067            BRANCH_ALWAYS(ppci.xl.bt_bo) &&
00068            !GET_BH(ppci))
00069             return true;
00070     }
00071     return isCondReturn();
00072 }
00073 
00074 bool Instruction::isCondReturn(){
00075     if(!ppci.lk.lk){
00076         if(IS_BCLR(ppci) &&
00077            !BRANCH_ALWAYS(ppci.xl.bt_bo))
00078             return true;
00079     }
00080     return false;
00081 }
00082 
00083 bool Instruction::isCall() { 
00084     if(ppci.lk.lk){
00085         if(IS_B(ppci))
00086             return true;
00087         if(IS_BC(ppci) && BRANCH_ALWAYS(ppci.b.bo))
00088             return true;
00089         if(IS_BC(ppci) && !BRANCH_ALWAYS(ppci.b.bo)) 
00090             return true; 
00091         if((IS_BCLR(ppci) || IS_BCCTR(ppci)) && BRANCH_ALWAYS(ppci.xl.bt_bo))
00092             return true;
00093     }
00094     return false; 
00095 }
00096 
00097 uint64_t Instruction::getTargetAddress(uint64_t insnAddr){
00098 
00099     ASSERT((isCondBranch() || isJump()) && 
00100            "FATAL : getTargetAddress can oly be called for cond branch and jump");;
00101 
00102     int32_t offset = 0x0;
00103 
00104     if(IS_B(ppci)){
00105         offset = ppci.i.li;
00106     } else if(IS_BC(ppci)){
00107         offset = ppci.b.bd;
00108     }
00109     offset <<= 2;
00110 
00111     if(ppci.lk.aa){
00112         return (uint64_t)offset;
00113     }
00114 
00115     return insnAddr+offset;
00116 }
00117 
00118 /**************************************************************************************
00119 xlc c                                            xlc++
00120 32                        64                        32                            64
00121 l       r31,104(r2)        ld         r31,192(r2)        l       r31,152(r2)            ld        r31,296(r2)
00122 
00123 cmpli     cr0,0x0,r4,0xb     cmpli     cr0,0x0,r4,0xb     cmpli     cr0,0x0,r3,0xb         cmpli     cr0,0x0,r3,0xb
00124 bgt     0x10000794         bgt     0x1000251c         bgt     0x10000085c         bgt     0x100002800 
00125 sli     r3,r3,0x2         sli     r3,r3,0x0        sli     r4,r3,0x2             sli     r3,r3,0x0
00126                         rldicr     r3,r3,0x3,0x39                                rldicr     r4,r3,0x3,0x39
00127                                                 addi     r3,0x84(r31)        addi     r3,0xe0(r31)
00128 lwzx     r3,r31,r3        ldx     r3,r31,r3        lwzx    r3,r3,r4            ldx     r3,r3,r4
00129 
00130 
00131 gnu c                                            gnu c++
00132 32                        64                        32                            64
00133 cmpli   7,r0,11            cmplwi  cr7,r0,11        cmpli   7,r0,11                cmplwi  cr7,r0,11
00134 bgt     7,0x10000b28     bgt-    cr7,0x100009e4    bgt     7,0x100013f4        bgt-    cr7,0x1000143c
00135 l       r0,104(r31)        lwz     r0,192(r31)        l       r0,104(r31)            lwz     r0,192(r31)
00136                         clrldi  r0,r0,32                                    clrldi  r0,r0,32
00137 rlinm   r9,r0,2,0,29    rldicr  r9,r0,2,61        rlinm   r9,r0,2,0,29        rldicr  r9,r0,2,61    
00138 l       r0,108(r2)        ld      r0,200(r2)        l       r0,192(r2)            ld      r0,368(r2)
00139 cax     r9,r9,r0        add     r9,r9,r0        cax     r9,r9,r0            add     r9,r9,r0
00140 l       r9,0(r9)        lwz     r0,0(r9)        l       r9,0(r9)            lwz     r0,0(r9)
00141 l       r0,108(r2)        ld      r9,200(r2)        l       r0,192(r2)            ld      r9,368(r2)
00142                         extsw   r0,r0                                        extsw   r0,r0
00143 cax     r9,r9,r0        add     r0,r0,r9        cax     r9,r9,r0            add     r0,r0,r9
00144 **************************************************************************************/
00145 
00146 bool Instruction::isIndirectJump() { 
00147     return (isIndirectJumpCtr() || isIndirectJumpLnk());
00148 }
00149 
00150 bool Instruction::isIndirectJumpCtr(){
00151     if(!ppci.lk.lk &&
00152        IS_BCCTR(ppci) &&
00153        BRANCH_ALWAYS(ppci.xl.bt_bo))
00154         return true;
00155     return false;
00156 }
00157 bool Instruction::isIndirectJumpLnk(){
00158     if(!ppci.lk.lk &&
00159        IS_BCLR(ppci) &&
00160        BRANCH_ALWAYS(ppci.xl.bt_bo) &&
00161        GET_BH(ppci))
00162         return true;
00163     return false;
00164 }
00165 
00166 bool Instruction::isOtherBranch(){
00167     if(ppci.lk.lk){
00168         if(IS_BCLR(ppci) && !BRANCH_ALWAYS(ppci.xl.bt_bo)){ 
00169             return true;
00170         }
00171         if(IS_BCCTR(ppci) && !BRANCH_ALWAYS(ppci.xl.bt_bo)){ 
00172             return true;
00173         }
00174     } else {
00175         if(IS_BCCTR(ppci) && !BRANCH_ALWAYS(ppci.xl.bt_bo)){ 
00176             return true; 
00177         }
00178     }
00179     return false;
00180 }
00181 
00182 bool Instruction::definesJTBaseAddress(){
00183     if(IS_LWZ(ppci) && (ppci.d.ra == REG_TOC))
00184         return true;
00185     if(IS_LD(ppci) && (ppci.ds.ra == REG_TOC))
00186         return true;
00187     return false;
00188 }
00189 int32_t Instruction::getJTBaseOffsetTOC(){
00190     ASSERT(definesJTBaseAddress());
00191     if(IS_LWZ(ppci))
00192         return ppci.d.d_ui_si;
00193     if(IS_LD(ppci))
00194         return (ppci.ds.ds << 2);
00195     return 0;
00196 }
00197 uint32_t Instruction::getJTBaseAddrTarget(){
00198     return ppci.d.rt_s_bf;
00199 }
00200 
00201 bool Instruction::definesJTEntryCount(){
00202     return IS_CMPLI(ppci);
00203 }
00204 uint32_t Instruction::getJTEntryCount(){
00205     return (uint32_t)(ppci.d.d_ui_si & 0x0000ffff);
00206 }
00207 
00208 bool Instruction::isAddBeforeJump(){
00209     return IS_ADD(ppci);
00210 }
00211 
00212 bool Instruction::isLoadBeforeJump(){
00213     return (IS_LDX(ppci) || IS_LWZX(ppci));
00214 }
00215 
00216 uint32_t Instruction::getLoadBeforeJumpSrc1(){
00217     return ppci.x.ra_sr;
00218 }
00219 
00220 bool Instruction::definesJTBaseAddrIndir(){
00221     return IS_ADDI(ppci);
00222 }
00223 
00224 int32_t Instruction::getJTBaseAddrIndirOffset(){
00225     ASSERT(definesJTBaseAddrIndir());
00226     return ppci.d.d_ui_si; 
00227 }
00228 
00229 uint32_t Instruction::getJTBaseAddrIndirSrc(){
00230     return ppci.d.ra;
00231 }
00232 
00233 
00234 #ifdef USE_DISASSEMBLER
00235 extern "C" int32_t print_insn_powerpc_for_meminst(uint64_t memaddr, uint32_t insn, int32_t dialect,char* buffer);
00236 #else
00237 int32_t print_insn_powerpc_for_meminst(uint64_t memaddr, uint32_t insn, int32_t dialect,char* buffer){
00238     if(buffer) strcpy(buffer,"no_insn");
00239     return 0;
00240 }
00241 #endif
00242 
00243 void Instruction::print(uint64_t insnAddr,bool is64Bit){
00244 
00245 #ifdef USE_DISASSEMBLER
00246     char buffer[1024];
00247     fprintf(stdout,"\t%#18llx : ",insnAddr);
00248     if(is64Bit){
00249         print_insn_powerpc_for_meminst(insnAddr,ppci.bits,67169,buffer);
00250     } else {
00251         print_insn_powerpc_for_meminst(insnAddr,ppci.bits,2,buffer);
00252     }
00253     fprintf(stdout,buffer);
00254 
00255     if(isCondBranch()){
00256         PRINT_DEBUG("\tisCondBranch");
00257     } else if(isJump()){
00258         PRINT_DEBUG("\tisJump");
00259     } else if(isCondReturn()){
00260         PRINT_DEBUG("\tisCondReturn");
00261     } else if(isReturn()){
00262         PRINT_DEBUG("\tisReturn");
00263     } else if(isCall()){
00264         PRINT_DEBUG("\tisCall");
00265     } else if(isIndirectJump()){
00266         PRINT_DEBUG("\tisIndirectJump");
00267     } else if(isMemoryDForm()){
00268         PRINT_DEBUG("\tisMemoryDForm");
00269     } else if(isMemoryDsForm()){
00270         PRINT_DEBUG("\tisMemoryDsForm");
00271     } else if(isMemoryXForm()){
00272         PRINT_DEBUG("\tisMemoryXForm");
00273     } else if(isUnhandledMemoryOp()){
00274         PRINT_DEBUG("\tisUnhandledMemoryOp");
00275     } else if(isFloatAForm()){
00276         PRINT_DEBUG("\tisFloatAForm");
00277     } else if(isFloatXForm()){
00278         PRINT_DEBUG("\tisFloatXForm");
00279     }
00280 #endif
00281 }
00282 
00283 void Instruction::print(char* buffer,uint64_t baseAddress,uint32_t sizeInBytes,bool is64Bit){
00284 #ifdef USE_DISASSEMBLER
00285     for(uint32_t i=0;i<sizeInBytes;i+=sizeof(uint32_t)){
00286         uint64_t insnAddr = baseAddress + i;
00287         uint32_t insnBits = 0;
00288         memcpy(&insnBits,buffer+i,sizeof(uint32_t));
00289         Instruction insn(insnBits);
00290         insn.print(insnAddr,is64Bit);
00291     }
00292 #endif
00293 }
00294 
00295 bool Instruction::isMemoryDForm(){
00296     return ((ppci.opc.opc >= opcode_Lwz) && 
00297             (ppci.opc.opc <= opcode_Stfdu));
00298 }
00299 bool Instruction::isMemoryDsForm(){
00300     return ((ppci.opc.opc == opcode_Ld) || 
00301             (ppci.opc.opc == opcode_Std));
00302 }
00303 bool Instruction::isMemoryXForm(){
00304     return ((ppci.opc.opc == opcode_Lwarx) && 
00305             memoryOperationXops->contains(ppci.x.xo));
00306 }
00307 bool Instruction::isUnhandledMemoryOp(){
00308     return ((ppci.opc.opc == opcode_Lwarx) && 
00309             !memoryOperationXops->contains(ppci.x.xo) &&
00310             ((ppci.x.xo & MEMORY_MASK) == MEMORY_MATCH));
00311 }
00312 
00313 bool Instruction::isFloatAForm(){
00314     return ((ppci.opc.opc == opcode_FdivsC) ||
00315             ((ppci.opc.opc == opcode_Fcmpu) && 
00316             ((ppci.x.xo & FOP_AFORM_MASK) == FOP_AFORM_MATCH)));
00317 }
00318 bool Instruction::isFloatXForm(){
00319     return ((ppci.opc.opc == opcode_Fcmpu) && 
00320             ((ppci.x.xo & FOP_AFORM_MASK) != FOP_AFORM_MATCH) &&
00321             ((ppci.x.xo & FOP_CONDREG_MASK) != FOP_CONDREG_MATCH) &&
00322             (ppci.x.xo != xcode_Mcrfs));
00323 }
00324 
00325 uint32_t Instruction::getDFormSrc1() 
00326 { 
00327     return ppci.d.ra; 
00328 }
00329 uint32_t Instruction::getDFormTgt() 
00330 { 
00331     return ppci.d.rt_s_bf; 
00332 }
00333 int32_t Instruction::getDFormImmediate() 
00334 { 
00335     return ppci.d.d_ui_si; 
00336 }
00337 int32_t Instruction::getDsFormImmediate() 
00338 { 
00339     return (ppci.ds.ds << 2); 
00340 }
00341 uint32_t Instruction::getXFormSrc1() 
00342 { 
00343     return ppci.x.ra_sr; 
00344 }
00345 uint32_t Instruction::getXFormSrc2() 
00346 { 
00347     return ppci.x.rb_sh; 
00348 }
00349 bool Instruction::isMemoryXFormButNoSrc2() 
00350 { 
00351     return (IS_LSWI(ppci) || IS_STSWI(ppci)); 
00352 }
00353 
00354 bool Instruction::isInLoadOffsetInsnRange(int32_t value){
00355     int32_t max = 0x7fff;
00356     int32_t min = -(max+1);
00357     if((min <= value) && (value <= max))
00358         return true;
00359     return false;
00360 }
00361 
00362 bool Instruction::isInJumpInsnRange(uint64_t from,uint64_t to){
00363     int32_t distance = to - from;
00364     ASSERT(!(distance & 0x3));
00365     distance >>= 2;
00366     int32_t max = 0x7fffff;
00367     int32_t min = -(max+1);
00368     if((min <= distance) && (distance <= max))
00369         return true;
00370     return false;
00371 }
00372 Instruction Instruction::generateJumpInsn(uint64_t from,uint64_t to){
00373     Instruction ret;
00374     ASSERT(isInJumpInsnRange(from,to));
00375     int32_t distance = to - from;
00376     distance >>= 2;
00377     ret.ppci.i.opc = opcode_BLA;
00378     ret.ppci.i.li = distance;
00379     ret.ppci.i.aa = 0;
00380     ret.ppci.i.lk = 0;
00381     return ret;
00382 }
00383 Instruction Instruction::generateAdd(uint32_t tgt,uint32_t src1,uint32_t src2){
00384     Instruction ret;
00385     ret.ppci.xo.opc = opcode_AddOC;
00386     ret.ppci.xo.xo = xcode_AddOC;
00387     ret.ppci.xo.oe = 0;
00388     ret.ppci.xo.rc = 0;
00389     ret.ppci.xo.rt = tgt;
00390     ret.ppci.xo.ra = src1;
00391     ret.ppci.xo.rb = src2;
00392     return ret;
00393 }
00394 
00395 Instruction Instruction::generateAddImm(uint32_t tgt,uint32_t src,int32_t value){
00396     Instruction ret;
00397     ret.ppci.d.opc = opcode_Addi;
00398     ret.ppci.d.rt_s_bf = tgt;
00399     ret.ppci.d.ra = src;
00400     ASSERT(isInLoadOffsetInsnRange(value));
00401     ret.ppci.d.d_ui_si = value;
00402     return ret;
00403 }
00404 
00405 Instruction Instruction::generateIncrement(uint32_t reg,int32_t value){
00406     return generateAddImm(reg,reg,value);
00407 }
00408 Instruction Instruction::generateLoadImmediate(uint32_t reg,int32_t value){
00409     return generateAddImm(reg,0,value);
00410 }
00411 
00412 Instruction Instruction::generateAddImmShifted(uint32_t tgt,uint32_t src,int32_t imm){
00413     Instruction ret;
00414     ret.ppci.d.opc = opcode_Addis;
00415     ret.ppci.d.rt_s_bf = tgt;
00416     ret.ppci.d.ra = src;
00417     ASSERT(isInLoadOffsetInsnRange(imm));
00418     ret.ppci.d.d_ui_si = imm;
00419     return ret;
00420 }
00421 Instruction Instruction::generateLoad32BitHigh(uint32_t reg,int32_t value){
00422     return generateAddImmShifted(reg,0,(value >> 16));
00423 }
00424 Instruction Instruction::generateOrImm(uint32_t tgt,uint32_t src,int32_t imm){
00425     Instruction ret;
00426     ret.ppci.d.opc = opcode_Ori;
00427     ret.ppci.d.rt_s_bf = src;
00428     ret.ppci.d.ra = tgt;
00429     ret.ppci.d.d_ui_si = imm;
00430     return ret;
00431 }
00432 Instruction Instruction::generateLoad32BitLow(uint32_t reg,int32_t value){
00433     return generateOrImm(reg,reg,(value & 0xffff));
00434 }
00435 
00436 Instruction Instruction::generateAnd(uint32_t tgt,uint32_t src1,uint32_t src2){
00437     Instruction ret;
00438     ret.ppci.x.opc = opcode_AndC;
00439     ret.ppci.x.xo = xcode_AndC;
00440     ret.ppci.x.rt_s_bf = src1;
00441     ret.ppci.x.ra_sr = tgt;
00442     ret.ppci.x.rb_sh = src2;
00443     ret.ppci.x.rc = 0;
00444     return ret;
00445 }
00446 
00447 Instruction Instruction::generateXorImm(uint32_t tgt,uint32_t src,int32_t imm){
00448     Instruction ret;
00449     ret.ppci.d.opc = opcode_Xori;
00450     ret.ppci.d.rt_s_bf = src;
00451     ret.ppci.d.ra = tgt;
00452     ret.ppci.d.d_ui_si = imm;
00453     return ret;
00454 }
00455 Instruction Instruction::generateXorImmShifted(uint32_t tgt,uint32_t src,int32_t imm){
00456     Instruction ret;
00457     ret.ppci.d.opc = opcode_Xoris;
00458     ret.ppci.d.rt_s_bf = src;
00459     ret.ppci.d.ra = tgt;
00460     ret.ppci.d.d_ui_si = imm;
00461     return ret;
00462 }
00463 Instruction Instruction::multiplyImmediate(uint32_t tgt,uint32_t src,int32_t imm){
00464     Instruction ret;
00465     ret.ppci.d.opc = opcode_Mulli;
00466     ret.ppci.d.rt_s_bf = tgt;
00467     ret.ppci.d.ra = src;
00468     ASSERT(isInLoadOffsetInsnRange(imm));
00469     ret.ppci.d.d_ui_si = imm;
00470     return ret;
00471 }
00472 
00473 Instruction Instruction::generateStoreDoubleFloat(uint32_t src,uint32_t base,int32_t offset){
00474     Instruction ret;
00475     ASSERT(!(offset & 0x3));
00476     ASSERT(isInLoadOffsetInsnRange(offset));
00477     ret.ppci.d.opc = opcode_Stfd;
00478     ret.ppci.d.rt_s_bf = src;
00479     ret.ppci.d.ra = base;
00480     ret.ppci.d.d_ui_si = offset;
00481     return ret;
00482 }
00483 Instruction Instruction::generateLoadDoubleFloat(uint32_t tgt,uint32_t base,int32_t offset){
00484     Instruction ret;
00485     ASSERT(!(offset & 0x3));
00486     ASSERT(isInLoadOffsetInsnRange(offset));
00487     ret.ppci.d.opc = opcode_Lfd;
00488     ret.ppci.d.rt_s_bf = tgt;
00489     ret.ppci.d.ra = base;
00490     ret.ppci.d.d_ui_si = offset;
00491     return ret;
00492 }
00493 Instruction Instruction::generateStoreWordFloat(uint32_t src,uint32_t base,int32_t offset){
00494     Instruction ret;
00495     ASSERT(!(offset & 0x3));
00496     ASSERT(isInLoadOffsetInsnRange(offset));
00497     ret.ppci.d.opc = opcode_Stfs;
00498     ret.ppci.d.rt_s_bf = src;
00499     ret.ppci.d.ra = base;
00500     ret.ppci.d.d_ui_si = offset;
00501     return ret;
00502 }
00503 Instruction Instruction::generateLoadWordFloat(uint32_t tgt,uint32_t base,int32_t offset){
00504     Instruction ret;
00505     ASSERT(!(offset & 0x3));
00506     ASSERT(isInLoadOffsetInsnRange(offset));
00507     ret.ppci.d.opc = opcode_Lfs;
00508     ret.ppci.d.rt_s_bf = tgt;
00509     ret.ppci.d.ra = base;
00510     ret.ppci.d.d_ui_si = offset;
00511     return ret;
00512 }
00513 
00514 Instruction Instruction::generateStoreDouble(uint32_t src,uint32_t base,int32_t offset){
00515     Instruction ret;
00516     ret.ppci.ds.opc = opcode_Std;
00517     ret.ppci.ds.xo = xcode_Std;
00518     ret.ppci.ds.rt_s = src;
00519     ret.ppci.ds.ra = base;
00520     ASSERT(!(offset & 0x3));
00521     ASSERT(isInLoadOffsetInsnRange(offset));
00522     offset >>= 2;
00523     ret.ppci.ds.ds = offset;
00524     return ret;
00525 }
00526 Instruction Instruction::generateLoadDouble(uint32_t tgt,uint32_t base,int32_t offset){
00527     Instruction ret;
00528     ret.ppci.ds.opc = opcode_Ld;
00529     ret.ppci.ds.xo = xcode_Ld;
00530     ret.ppci.ds.rt_s = tgt;
00531     ret.ppci.ds.ra = base;
00532     ASSERT(!(offset & 0x3));
00533     ASSERT(isInLoadOffsetInsnRange(offset));
00534     offset >>= 2;
00535     ret.ppci.ds.ds = offset;
00536     return ret;
00537 }
00538 
00539 Instruction Instruction::generateStoreWord(uint32_t src,uint32_t base,int32_t offset){
00540     Instruction ret;
00541     ret.ppci.d.opc = opcode_Stw;
00542     ret.ppci.d.rt_s_bf = src;
00543     ret.ppci.d.ra = base;
00544     ASSERT(!(offset & 0x3));
00545     ASSERT(isInLoadOffsetInsnRange(offset));
00546     ret.ppci.d.d_ui_si = offset;
00547     return ret;
00548 }
00549 Instruction Instruction::generateLoadWordIndx(uint32_t tgt,uint32_t base1,uint32_t base2){
00550     Instruction ret;
00551     ret.ppci.x.opc = opcode_Lwzx;
00552     ret.ppci.x.xo = xcode_Lwzx;
00553     ret.ppci.x.rt_s_bf = tgt;
00554     ret.ppci.x.ra_sr = base1;
00555     ret.ppci.x.rb_sh = base2;
00556     ret.ppci.x.rc = 0;
00557     return ret;
00558 }
00559 Instruction Instruction::generateStoreWordIndx(uint32_t src,uint32_t base1,uint32_t base2){
00560     Instruction ret;
00561     ret.ppci.x.opc = opcode_Stwx;
00562     ret.ppci.x.xo = xcode_Stwx;
00563     ret.ppci.x.rt_s_bf = src;
00564     ret.ppci.x.ra_sr = base1;
00565     ret.ppci.x.rb_sh = base2;
00566     ret.ppci.x.rc = 0;
00567     return ret;
00568 }
00569 
00570 Instruction Instruction::generateLoadDoubleIndx(uint32_t tgt,uint32_t base1,uint32_t base2){
00571     Instruction ret;
00572     ret.ppci.x.opc = opcode_Ldx;
00573     ret.ppci.x.xo = xcode_Ldx;
00574     ret.ppci.x.rt_s_bf = tgt;
00575     ret.ppci.x.ra_sr = base1;
00576     ret.ppci.x.rb_sh = base2;
00577     ret.ppci.x.rc = 0;
00578     return ret;
00579 }
00580 Instruction Instruction::generateStoreDoubleIndx(uint32_t src,uint32_t base1,uint32_t base2){
00581     Instruction ret;
00582     ret.ppci.x.opc = opcode_Stdx;
00583     ret.ppci.x.xo = xcode_Stdx;
00584     ret.ppci.x.rt_s_bf = src;
00585     ret.ppci.x.ra_sr = base1;
00586     ret.ppci.x.rb_sh = base2;
00587     ret.ppci.x.rc = 0;
00588     return ret;
00589 }
00590 
00591 Instruction Instruction::generateLoadWord(uint32_t tgt,uint32_t base,int32_t offset){
00592     Instruction ret;
00593     ret.ppci.d.opc = opcode_Lwz;
00594     ret.ppci.d.rt_s_bf = tgt;
00595     ret.ppci.d.ra = base;
00596     ASSERT(!(offset & 0x3));
00597     ASSERT(isInLoadOffsetInsnRange(offset));
00598     ret.ppci.d.d_ui_si = offset;
00599     return ret;
00600 }
00601 Instruction Instruction::generateMoveToSPR(uint32_t tgt,uint32_t regcode){
00602     Instruction ret;
00603     ret.ppci.xfx.opc = opcode_Mtspr;
00604     ret.ppci.xfx.xo = xcode_Mtspr;
00605     ret.ppci.xfx.rt_rs = tgt;
00606     ret.ppci.xfx.spr_tbr = regcode;
00607     return ret;
00608 }
00609 
00610 Instruction Instruction::generateMoveFromSPR(uint32_t src,uint32_t regcode){
00611     Instruction ret;
00612     ret.ppci.xfx.opc = opcode_Mfspr;
00613     ret.ppci.xfx.xo = xcode_Mfspr;
00614     ret.ppci.xfx.rt_rs = src;
00615     ret.ppci.xfx.spr_tbr = regcode;
00616     return ret;
00617 }
00618 Instruction Instruction::generateMoveFromCR(uint32_t tgt){
00619     Instruction ret;
00620     ret.ppci.xfx.opc = opcode_Mfcr;
00621     ret.ppci.xfx.xo = xcode_Mfcr;
00622     ret.ppci.xfx.rt_rs = tgt;
00623     ret.ppci.xfx.spr_tbr = 0x0;
00624     return ret;
00625 }
00626 Instruction Instruction::generateMoveToCR(uint32_t src){
00627     Instruction ret;
00628     ret.ppci.xfx.opc = opcode_Mtcrf;
00629     ret.ppci.xfx.xo = xcode_Mtcrf;
00630     ret.ppci.xfx.rt_rs = src;
00631     ret.ppci.xfx.spr_tbr = 0x1fe;
00632     return ret;
00633 }
00634 Instruction Instruction::generateMoveFromFPSCR(uint32_t tgt){
00635     Instruction ret;
00636     ret.ppci.x.opc = opcode_MffsC;
00637     ret.ppci.x.xo = xcode_MffsC;
00638     ret.ppci.x.rt_s_bf = tgt;
00639     ret.ppci.x.rc = 0;
00640     return ret;
00641 }
00642 Instruction Instruction::generateMoveToFPSCR(uint32_t src){
00643     Instruction ret;
00644     ret.ppci.xfl.opc = opcode_MtfsfC;
00645     ret.ppci.xfl.xo = xcode_MtfsfC;
00646     ret.ppci.xfl.frb = src;
00647     ret.ppci.xfl.flm = 0xff;
00648     ret.ppci.xfl.rc = 0;
00649     return ret;
00650 }
00651 
00652 Instruction Instruction::generateCallToCTR(){
00653     Instruction ret;
00654     ret.ppci.xl.opc = opcode_BcctrL;
00655     ret.ppci.xl.xo = xcode_BcctrL;
00656     ret.ppci.xl.lk = 1;
00657     ret.ppci.xl.bt_bo = 0x14; 
00658     ret.ppci.xl.ba_bi = 0x0;
00659     ret.ppci.xl.bb = 0x0;
00660     return ret;
00661 }
00662 
00663 Instruction Instruction::generateReturnToLnk(){
00664     Instruction ret;
00665     ret.ppci.xl.opc = opcode_BclrL;
00666     ret.ppci.xl.xo = xcode_BclrL;
00667     ret.ppci.xl.lk = 0;
00668     ret.ppci.xl.bt_bo = 0x14; 
00669     ret.ppci.xl.ba_bi = 0x0;
00670     ret.ppci.xl.bb = 0x0;
00671     return ret;
00672 }
00673 
00674 Instruction Instruction::generateCallToImmediate(uint64_t from,uint64_t to){
00675     Instruction ret = generateJumpInsn(from,to);
00676     ret.ppci.i.lk = 1;
00677     return ret;
00678 }
00679 
00680 Instruction Instruction::generateMoveReg(uint32_t from,uint32_t to){
00681     Instruction ret;
00682     ret.ppci.x.opc = opcode_OrC;
00683     ret.ppci.x.xo = xcode_OrC;
00684     ret.ppci.x.rt_s_bf = from;
00685     ret.ppci.x.ra_sr = to;
00686     ret.ppci.x.rb_sh = from;
00687     ret.ppci.x.rc = 0;
00688     return ret;
00689 }
00690 
00691 Instruction Instruction::generateSPIncrementWord(int32_t offset){
00692     Instruction ret;
00693     ret.ppci.d.opc = opcode_Stwu;
00694     ret.ppci.d.rt_s_bf = REG_SP;
00695     ret.ppci.d.ra = REG_SP;
00696     ASSERT(!(offset & 0x3));
00697     ASSERT(isInLoadOffsetInsnRange(offset));
00698     ret.ppci.d.d_ui_si = offset;
00699     return ret;
00700 }
00701 Instruction Instruction::generateSPIncrementDouble(int32_t offset){
00702     Instruction ret;
00703     ret.ppci.ds.opc = opcode_Stdu;
00704     ret.ppci.ds.xo = xcode_Stdu;
00705     ret.ppci.ds.rt_s = REG_SP;
00706     ret.ppci.ds.ra = REG_SP;
00707     ASSERT(!(offset & 0x3));
00708     ASSERT(isInLoadOffsetInsnRange(offset));
00709     offset >>= 2;
00710     ret.ppci.ds.ds = offset;
00711     return ret;
00712 }
00713 
00714 Instruction Instruction::generateCompare(uint32_t reg1,uint32_t reg2,uint32_t field){
00715     Instruction ret;
00716     ret.ppci.x.opc = opcode_Cmpl;
00717     ret.ppci.x.xo = xcode_Cmpl;
00718     ret.ppci.x.rt_s_bf = field << 2;
00719     ret.ppci.x.ra_sr = reg1;
00720     ret.ppci.x.rb_sh = reg2;
00721     return ret;
00722 }
00723 
00724 Instruction Instruction::generateCondBranch(uint32_t field,uint32_t op,uint32_t tf,int32_t offset){
00725     Instruction ret;
00726     ret.ppci.b.opc = opcode_BcLA;
00727     ret.ppci.b.bo = (0x7 | (tf << 3));
00728     ret.ppci.b.bi = (field << 2) + op;
00729     ASSERT(!(offset & 0x3));
00730     ASSERT(isInLoadOffsetInsnRange(offset));
00731     offset >>= 2;
00732     ret.ppci.b.bd = offset;
00733     ret.ppci.b.aa = 0x0;
00734     ret.ppci.b.lk = 0x0;
00735     return ret;
00736 }
00737 
00738 bool Instruction::isMemoryDFormFloat(){
00739     return ((ppci.opc.opc >= opcode_Lfs) && 
00740             (ppci.opc.opc <= opcode_Stfdu));
00741 }

Generated on Mon Jan 28 11:08:32 2008 for PMaCInstrumentor by doxygen 1.3.5