disppc.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,470 行 · 第 1/3 页
C
1,470 行
code.full = ins->opcode;
PPCFloatdb( h, d, ins );
switch( ins->type ) {
case DI_PPC_mffs:
ins->num_ops = 1;
break;
case DI_PPC_mtfsf:
ins->op[0].type = DO_IMMED;
ins->op[0].base = DR_NONE;
ins->op[0].value = code.hi.math.FM;
break;
default:
break;
}
return( DHR_DONE );
}
dis_handler_return PPCMem1( dis_handle *h, void *d, dis_dec_ins *ins )
{
ppc_ins code;
code.full = ins->opcode;
ins->num_ops = 2;
ins->op[0].type = DO_REG;
ins->op[0].base = code.hi.general.second + DR_PPC_r0;
ins->op[1].type = DO_MEMORY_ABS;
ins->op[1].base = code.hi.general.first + DR_PPC_r0;
ins->op[1].value = SEX( code.lo.immediate, 15 );
if( code.hi.general.floating ) {
if( code.hi.general.type & 0x2 ) {
ins->op[1].ref_type = DRT_PPC_SFLOAT;
} else {
ins->op[1].ref_type = DRT_PPC_DFLOAT;
}
} else {
switch( code.hi.general.type ) {
case 0x1:
case 0x3:
ins->op[1].ref_type = DRT_PPC_BYTE;
break;
case 0x4:
case 0x5:
case 0x6:
ins->op[1].ref_type = DRT_PPC_HWORD;
break;
case 0x7:
ins->op[1].ref_type = DRT_PPC_MWORD;
break;
case 0x0:
case 0x2:
ins->op[1].ref_type = DRT_PPC_WORD;
break;
}
}
return( DHR_DONE );
}
dis_handler_return PPCMemD1( dis_handle *h, void *d, dis_dec_ins *ins )
{
ppc_ins code;
code.full = ins->opcode;
ins->num_ops = 2;
ins->op[0].type = DO_REG;
ins->op[0].base = code.hi.general.second + DR_PPC_r0;
ins->op[1].type = DO_MEMORY_ABS;
ins->op[1].base = code.hi.general.first + DR_PPC_r0;
ins->op[1].value = SEX( code.lo.immediate & ~0x3, 15 );
ins->op[1].ref_type = DRT_PPC_DWORD;
return( DHR_DONE );
}
dis_handler_return PPCMem2( dis_handle *h, void *d, dis_dec_ins *ins )
{
ppc_ins code;
code.full = ins->opcode;
ins->num_ops = 3;
ins->op[0].type = DO_REG;
ins->op[0].base = code.hi.general.second + DR_PPC_r0;
ins->op[1].type = DO_REG;
ins->op[1].base = code.hi.general.first + DR_PPC_r0;
ins->op[2].type = DO_REG;
ins->op[2].base = code.lo.math.rB + DR_PPC_r0;
ins->op[1].extra |= PE_XFORM;
switch( code.lo.math.OE ) {
case 0:
switch( code.lo.math.type1 & 5 ) {
case 0:
ins->op[1].ref_type = DRT_PPC_WORD;
break;
case 1:
ins->op[1].ref_type = DRT_PPC_BYTE;
break;
case 4:
if( code.lo.math.type2 == 1 ) {
ins->op[1].ref_type = DRT_PPC_SWORD;
break;
} // fall through
case 5:
ins->op[1].ref_type = DRT_PPC_HWORD;
break;
}
break;
case 1:
switch( code.lo.math.type2 ) {
case 1:
ins->op[1].ref_type = DRT_PPC_SWORD;
break;
case 2:
if( code.lo.math.type1 & (1<<2) ) {
ins->op[1].ref_type = DRT_PPC_BRHWORD;
} else {
ins->op[1].ref_type = DRT_PPC_BRWORD;
}
break;
case 3:
if( code.lo.math.type1 & 1 ) {
ins->op[1].ref_type = DRT_PPC_DFLOAT;
} else {
ins->op[1].ref_type = DRT_PPC_SFLOAT;
}
break;
}
break;
}
if( code.lo.math.Rc ) {
ins->flags |= DIF_PPC_RC;
}
return( DHR_DONE );
}
dis_handler_return PPCMemD2( dis_handle *h, void *d, dis_dec_ins *ins )
{
ppc_ins code;
code.full = ins->opcode;
ins->num_ops = 3;
ins->op[0].type = DO_REG;
ins->op[0].base = code.hi.general.second + DR_PPC_r0;
ins->op[1].type = DO_REG;
ins->op[1].base = code.hi.general.first + DR_PPC_r0;
ins->op[2].type = DO_REG;
ins->op[2].base = code.lo.math.rB + DR_PPC_r0;
ins->op[1].extra |= PE_XFORM;
ins->op[1].ref_type = DRT_PPC_DWORD;
return( DHR_DONE );
}
dis_handler_return PPCMem3( dis_handle *h, void *d, dis_dec_ins *ins )
{
ppc_ins code;
code.full = ins->opcode;
ins->num_ops = 3;
ins->op[0].type = DO_REG;
ins->op[0].base = code.hi.general.second + DR_PPC_r0;
ins->op[1].type = DO_REG;
ins->op[1].base = code.hi.general.first + DR_PPC_r0;
ins->op[2].type = DO_IMMED;
ins->op[2].value = code.lo.general.third;
ins->op[1].ref_type = DRT_PPC_SWORD;
return( DHR_DONE );
}
dis_handler_return PPCFloatMem1( dis_handle *h, void *d, dis_dec_ins *ins )
{
PPCMem1( h, d, ins );
ins->op[0].base += DR_PPC_f0 - DR_PPC_r0;
return( DHR_DONE );
}
dis_handler_return PPCFloatMem2( dis_handle *h, void *d, dis_dec_ins *ins )
{
PPCMem2( h, d, ins );
ins->op[0].base += DR_PPC_f0 - DR_PPC_r0;
return( DHR_DONE );
}
dis_handler_return PPCBranch( dis_handle *h, void *d, dis_dec_ins *ins )
{
ppc_ins code;
int magic;
code.full = ins->opcode;
if( code.lo.branch.LK ) {
ins->flags |= DIF_PPC_LK;
}
magic = 2;
switch( ins->type ) {
case DI_PPC_b:
magic = 0; // fall through
case DI_PPC_bc:
magic++; // magic=1 for b, 3 for bc
if( code.b.AA ) {
ins->flags |= DIF_PPC_AA;
ins->op[magic-1].type = DO_ABSOLUTE;
} else {
ins->op[magic-1].type = DO_RELATIVE;
}
// fall through
case DI_PPC_bcctr:
case DI_PPC_bclr:
ins->num_ops = magic; // magic=2 for bcctr, bclr
break;
default:
break;
}
switch( ins->type ) {
case DI_PPC_b:
ins->op[0].value = SEX( code.b.LI, 23 ) << 2;
break;
case DI_PPC_bc:
ins->op[2].value = SEX( code.lo.branch.BD, 13 ) << 2;
ins->op[2].op_position = 0;
// fall through
case DI_PPC_bcctr:
case DI_PPC_bclr:
ins->op[0].type = DO_IMMED;
ins->op[0].value = code.hi.general.second;
ins->op[0].op_position = 3;
ins->op[1].type = DO_IMMED;
ins->op[1].value = code.hi.general.first;
ins->op[1].op_position = 2;
break;
default:
break;
}
return( DHR_DONE );
}
dis_handler_return PPCCompare( dis_handle *h, void *d, dis_dec_ins *ins )
{
ppc_ins code;
code.full = ins->opcode;
ins->num_ops = 4;
ins->op[0].type = DO_REG;
ins->op[0].base = code.hi.compare.crfD + DR_PPC_cr0;
ins->op[1].type = DO_IMMED;
ins->op[1].value = code.hi.compare.L;
ins->op[2].type = DO_REG;
ins->op[2].base = code.hi.compare.rA + DR_PPC_r0;
switch( ins->type ) {
case DI_PPC_cmp:
case DI_PPC_cmpl:
ins->op[3].type = DO_REG;
ins->op[3].base = code.lo.math.rB + DR_PPC_r0;
break;
case DI_PPC_cmpi:
ins->op[3].type = DO_IMMED;
ins->op[3].value = SEX( code.lo.immediate, 15 );
break;
case DI_PPC_cmpli:
ins->op[3].type = DO_IMMED;
ins->op[3].value = code.lo.immediate;
default:
break;
}
return( DHR_DONE );
}
dis_handler_return PPCCondition( dis_handle *h, void *d, dis_dec_ins *ins )
{
ppc_ins code;
code.full = ins->opcode;
ins->op[0].type = DO_REG;
ins->op[0].base = code.hi.general.second + DR_PPC_crb0;
switch( ins->type ) {
case DI_PPC_mtfsb0:
case DI_PPC_mtfsb1:
ins->num_ops = 1;
break;
default:
ins->num_ops = 3;
ins->op[1].type = DO_REG;
ins->op[1].base = code.hi.general.first + DR_PPC_crb0;
ins->op[2].type = DO_REG;
ins->op[2].base = code.lo.math.rB + DR_PPC_crb0;
break;
}
if( code.lo.general.Rc ) {
ins->flags |= DIF_PPC_RC;
}
return( DHR_DONE );
}
dis_handler_return PPCConditionField( dis_handle *h, void *d, dis_dec_ins *ins )
{
ppc_ins code;
code.full = ins->opcode;
ins->op[0].type = DO_REG;
ins->op[0].base = code.hi.condition.crfD + DR_PPC_cr0;
switch( ins->type ) {
case DI_PPC_mcrf:
case DI_PPC_mcrfs:
ins->num_ops = 2;
ins->op[1].type = DO_REG;
ins->op[1].base = code.hi.condition.crfS + DR_PPC_cr0;
break;
case DI_PPC_mcrxr:
ins->num_ops = 1;
break;
case DI_PPC_mtfsfi:
ins->num_ops = 2;
ins->op[1].type = DO_IMMED;
ins->op[1].value = code.lo.condition.IMM;
break;
default:
break;
}
return( DHR_DONE );
}
dis_handler_return PPCSpecial( dis_handle *h, void *d, dis_dec_ins *ins )
{
ppc_ins code;
int magic = 0;
code.full = ins->opcode;
ins->num_ops = 2;
switch( ins->type ) {
case DI_PPC_mfspr:
case DI_PPC_mfsr:
magic = 0;
break;
case DI_PPC_mtspr:
case DI_PPC_mtsr:
case DI_PPC_mtcrf:
magic = 1;
break;
default:
break;
}
ins->op[magic].type = DO_REG;
ins->op[magic].base = code.hi.general.second + DR_PPC_r0;
magic = 1-magic;
ins->op[magic].type = DO_IMMED;
switch( ins->type ) {
case DI_PPC_mfspr:
case DI_PPC_mtspr:
ins->op[magic].value = MK_SPR( code.lo.general.third, code.hi.general.first );
break;
case DI_PPC_mfsr:
case DI_PPC_mtsr:
ins->op[magic].value = code.hi.general.first;
break;
case DI_PPC_mtcrf:
ins->op[magic].value = code.CRM.CRM;
break;
default:
break;
}
return( DHR_DONE );
}
dis_handler_return PPCShiftImmed( dis_handle *h, void *d, dis_dec_ins *ins )
{
ppc_ins code;
PPCImmed2( h, d, ins );
code.full = ins->opcode;
ins->op[2].value = code.lo.general.third;
if( code.lo.general.Rc ) {
ins->flags |= DIF_PPC_RC;
}
return( DHR_DONE );
}
dis_handler_return PPCShiftImmedD( dis_handle *h, void *d, dis_dec_ins *ins )
{
ppc_ins code;
PPCImmed2( h, d, ins );
code.full = ins->opcode;
ins->op[2].value = code.lo.xs_form.sh | (code.lo.xs_form.sh_5 << 5);
if( code.lo.general.Rc ) {
ins->flags |= DIF_PPC_RC;
}
return( DHR_DONE );
}
dis_handler_return PPCRotate( dis_handle *h, void *d, dis_dec_ins *ins )
{
ppc_ins code;
PPCMath2( h, d, ins );
code.full = ins->opcode;
ins->num_ops = 5;
switch( ins->type ) {
case DI_PPC_rlwimi:
case DI_PPC_rlwinm:
ins->op[2].type = DO_IMMED;
ins->op[2].base = DR_NONE;
ins->op[2].value = code.lo.general.third;
break;
default:
break;
}
ins->op[3].type = DO_IMMED;
ins->op[3].value = code.lo.general.second;
ins->op[4].type = DO_IMMED;
ins->op[4].value = code.lo.general.first;
if( code.lo.general.Rc ) {
ins->flags |= DIF_PPC_RC;
}
return( DHR_DONE );
}
dis_handler_return PPCRotateD( dis_handle *h, void *d, dis_dec_ins *ins )
{
ppc_ins code;
PPCMath2( h, d, ins );
code.full = ins->opcode;
ins->num_ops = 4;
ins->op[3].type = DO_IMMED;
ins->op[3].value = code.lo.mds_form.mb;
if( code.lo.general.Rc ) {
ins->flags |= DIF_PPC_RC;
}
return( DHR_DONE );
}
dis_handler_return PPCRotateImmD( dis_handle *h, void *d, dis_dec_ins *ins )
{
ppc_ins code;
PPCMath2( h, d, ins );
code.full = ins->opcode;
ins->num_ops = 4;
ins->op[2].type = DO_IMMED;
ins->op[2].base = DR_NONE;
ins->op[2].value = code.lo.md_form.sh | (code.lo.md_form.sh_5 << 5);
ins->op[3].type = DO_IMMED;
ins->op[3].value = code.lo.mds_form.mb;
if( code.lo.general.Rc ) {
ins->flags |= DIF_PPC_RC;
}
return( DHR_DONE );
}
dis_handler_return PPCTrap( dis_handle *h, void *d, dis_dec_ins *ins )
{
ppc_ins code;
code.full = ins->opcode;
ins->num_ops = 3;
ins->op[0].type = DO_IMMED;
ins->op[0].value = code.hi.general.second;
ins->op[0].op_position = 3;
ins->op[1].type = DO_REG;
ins->op[1].base = code.hi.general.first + DR_PPC_r0;
switch( ins->type ) {
case DI_PPC_tw:
case DI_PPC_td:
ins->op[2].type = DO_REG;
ins->op[2].base = code.lo.math.rB + DR_PPC_r0;
break;
case DI_PPC_twi:
case DI_PPC_tdi:
ins->op[2].type = DO_IMMED;
ins->op[2].value = SEX( code.lo.immediate, 15 );
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?