dis_handler_return SPARCSetHi( dis_handle*h, void *d, dis_dec_ins *ins ) { sparc_ins code; code.full = _SparcIns( ins->opcode ); ins->op[0].type = DO_IMMED; ins->op[0].value = SEX( code.sethi.imm22, 21 ); ins->op[1].type = DO_REG; ins->op[1].base = _SparcReg( code.sethi.rd ); ins->num_ops = 2; return( DHR_DONE ); }
dis_handler_return SPARCBranch( dis_handle *h, void *d, dis_dec_ins *ins ) { sparc_ins code; code.full = _SparcIns( ins->opcode ); ins->op[0].type = DO_RELATIVE; ins->op[0].value = ( SEX( code.branch.disp22, 21 ) ) * sizeof( ins->opcode ); if( code.branch.anul != 0 ) { ins->flags.u.sparc |= DIF_SPARC_ANUL; } ins->num_ops = 1; return( DHR_DONE ); }
dis_handler_return SPARCCall( dis_handle *h, void *d, dis_dec_ins *ins ) { sparc_ins code; code.full = _SparcIns( ins->opcode ); ins->op[0].type = DO_RELATIVE; // BartoszP 16.10.2005 // SPARC Architecture Manual says: // CALL saves self address not next instruction into the %o7 register //ins->op[0].value = ( SEX( code.call.disp, 29 ) + 1) * sizeof( ins->opcode ); ins->op[0].value = ( SEX( code.call.disp, 29 ) ) * sizeof( ins->opcode ); ins->num_ops = 1; return( DHR_DONE ); }
dis_handler_return SPARCFPop3( dis_handle *h, void *d, dis_dec_ins *ins ) { sparc_ins code; code.full = _SparcIns( ins->opcode ); ins->op[ 0 ].type = DO_REG; ins->op[ 0 ].base = _SparcFReg( code.op3opf.rs1 ); ins->op[ 1 ].type = DO_REG; ins->op[ 1 ].base = _SparcFReg( code.op3opf.rs2 ); ins->op[ 2 ].type = DO_REG; ins->op[ 2 ].base = _SparcFReg( code.op3opf.rd ); ins->num_ops = 3; return( DHR_DONE ); }
dis_handler_return SPARCMem( dis_handle *h, void *d, dis_dec_ins *ins ) { sparc_ins code; int mem_op; int reg_op; code.full = _SparcIns( ins->opcode ); getOpIndices( code, &mem_op, ®_op ); ins->op[ reg_op ].type = DO_REG; ins->op[ reg_op ].base = _SparcReg( code.op3.rd ); ins->op[ mem_op ].ref_type = integerRefTypes[ code.op3.opcode_3 & 0x03 ]; doSparcMem( h, d, &ins->op[ mem_op ], code ); ins->num_ops = 2; return( DHR_DONE ); }
dis_handler_return SPARCFPop2( dis_handle *h, void *d, dis_dec_ins *ins ) { sparc_ins code; code.full = _SparcIns( ins->opcode ); if( code.op3opf.opcode_3 == 0x35 ) { // fcmp ins->op[ 0 ].type = DO_REG; ins->op[ 0 ].base = _SparcFReg( code.op3opf.rs1 ); ins->op[ 1 ].type = DO_REG; ins->op[ 1 ].base = _SparcFReg( code.op3opf.rs2 ); } else { ins->op[ 0 ].type = DO_REG; ins->op[ 0 ].base = _SparcFReg( code.op3opf.rs2 ); ins->op[ 1 ].type = DO_REG; ins->op[ 1 ].base = _SparcFReg( code.op3opf.rd ); } ins->num_ops = 2; return( DHR_DONE ); }
dis_handler_return SPARCOp3( dis_handle *h, void *d, dis_dec_ins *ins ) { sparc_ins code; code.full = _SparcIns( ins->opcode ); ins->op[ 0 ].type = DO_REG; ins->op[ 0 ].base = _SparcReg( code.op3.rs1 ); ins->op[ 2 ].type = DO_REG; ins->op[ 2 ].base = _SparcReg( code.op3.rd ); if( code.op3.imm != 0 ) { ins->op[ 1 ].type = DO_IMMED; ins->op[ 1 ].base = DR_NONE; ins->op[ 1 ].value = SEX( code.op3imm.simm13, 12 ); } else { ins->op[ 1 ].type = DO_REG; ins->op[ 1 ].base = _SparcReg( code.op3.rs2 ); ins->op[ 1 ].value = 0; } ins->num_ops = 3; return( DHR_DONE ); }
dis_handler_return SPARCMemC( dis_handle *h, void *d, dis_dec_ins *ins ) { sparc_ins code; int mem_op; int reg_op; code.full = _SparcIns( ins->opcode ); getOpIndices( code, &mem_op, ®_op ); ins->op[ reg_op ].type = DO_REG; ins->op[ reg_op ].base = _SparcCReg( code.op3.rd ); ins->op[ mem_op ].ref_type = coproRefTypes[ code.op3.opcode_3 & 0x03 ]; doSparcMem( h, d, &ins->op[ mem_op ], code ); if( code.op3.opcode_3 == 0x31 || code.op3.opcode_3 == 0x35 ) { // special case for ldcsr/stcsr instructions ins->op[ reg_op ].base = DR_SPARC_csr; } if( code.op3.opcode_3 == 0x36 ) { // another special case - stdcq instruction ins->op[ reg_op ].base = DR_SPARC_cq; } ins->num_ops = 2; return( DHR_DONE ); }