--- np2/i386c/ia32/instructions/ctrl_trans.c 2003/12/08 00:55:32 1.1 +++ np2/i386c/ia32/instructions/ctrl_trans.c 2004/03/05 14:17:36 1.13 @@ -1,4 +1,4 @@ -/* $Id: ctrl_trans.c,v 1.1 2003/12/08 00:55:32 yui Exp $ */ +/* $Id: ctrl_trans.c,v 1.13 2004/03/05 14:17:36 monaka Exp $ */ /* * Copyright (c) 2002-2003 NONAKA Kimihiro @@ -41,38 +41,41 @@ void JMP_Jb(void) { - DWORD ip; + UINT32 ip; CPU_WORKCLOCK(7); GET_PCBYTESD(ip); ADD_EIP(ip); + CPU_PREFETCH_CLEAR(); } void JMP_Jw(void) { - WORD ip; + UINT32 ip; CPU_WORKCLOCK(7); - GET_PCWORD(ip); + GET_PCWORDS(ip); ADD_EIP(ip); + CPU_PREFETCH_CLEAR(); } void JMP_Jd(void) { - DWORD ip; + UINT32 ip; CPU_WORKCLOCK(7); GET_PCDWORD(ip); ADD_EIP(ip); + CPU_PREFETCH_CLEAR(); } void -JMP_Ew(DWORD op) +JMP_Ew(UINT32 op) { - DWORD madr; - WORD new_ip; + UINT32 madr; + UINT32 new_ip; if (op >= 0xc0) { CPU_WORKCLOCK(7); @@ -87,10 +90,10 @@ JMP_Ew(DWORD op) } void -JMP_Ed(DWORD op) +JMP_Ed(UINT32 op) { - DWORD madr; - DWORD new_ip; + UINT32 madr; + UINT32 new_ip; if (op >= 0xc0) { CPU_WORKCLOCK(7); @@ -107,8 +110,8 @@ JMP_Ed(DWORD op) void JMP16_Ap(void) { - WORD new_ip; - WORD new_cs; + UINT32 new_ip; + UINT16 new_cs; CPU_WORKCLOCK(11); GET_PCWORD(new_ip); @@ -126,8 +129,8 @@ JMP16_Ap(void) void JMP32_Ap(void) { - DWORD new_ip; - WORD new_cs; + UINT32 new_ip; + UINT16 new_cs; CPU_WORKCLOCK(11); GET_PCDWORD(new_ip); @@ -143,15 +146,15 @@ JMP32_Ap(void) } void -JMP16_Ep(DWORD op) +JMP16_Ep(UINT32 op) { - DWORD madr; - WORD new_ip; - WORD new_cs; + UINT32 madr; + UINT32 new_ip; + UINT16 new_cs; CPU_WORKCLOCK(11); if (op < 0xc0) { - madr = get_ea(op); + madr = calc_ea_dst(op); new_ip = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); new_cs = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr + 2); if (!CPU_STAT_PM || CPU_STAT_VM86) { @@ -168,15 +171,15 @@ JMP16_Ep(DWORD op) } void -JMP32_Ep(DWORD op) +JMP32_Ep(UINT32 op) { - DWORD madr; - DWORD new_ip; - WORD new_cs; + UINT32 madr; + UINT32 new_ip; + UINT16 new_cs; CPU_WORKCLOCK(11); if (op < 0xc0) { - madr = get_ea(op); + madr = calc_ea_dst(op); new_ip = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); new_cs = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr + 4); if (!CPU_STAT_PM || CPU_STAT_VM86) { @@ -829,70 +832,68 @@ LOOP_Jb(void) void CALL_Aw(void) { - WORD ip; + SINT32 ip; CPU_WORKCLOCK(7); - GET_PCWORD(ip); + GET_PCWORDS(ip); PUSH0_16(CPU_IP); ADD_EIP(ip); + CPU_PREFETCH_CLEAR(); } void CALL_Ad(void) { - DWORD ip; + UINT32 ip; CPU_WORKCLOCK(7); GET_PCDWORD(ip); PUSH0_32(CPU_EIP); ADD_EIP(ip); + CPU_PREFETCH_CLEAR(); } void -CALL_Ew(DWORD op) +CALL_Ew(UINT32 op) { - DWORD madr; - WORD new_ip; + UINT32 madr; + UINT32 new_ip; if (op >= 0xc0) { CPU_WORKCLOCK(7); new_ip = *(reg16_b20[op]); - PUSH0_16(CPU_IP); - SET_EIP(new_ip); } else { CPU_WORKCLOCK(11); madr = calc_ea_dst(op); new_ip = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); - PUSH0_16(CPU_IP); - SET_EIP(new_ip); } + PUSH0_16(CPU_IP); + SET_EIP(new_ip); } void -CALL_Ed(DWORD op) +CALL_Ed(UINT32 op) { - DWORD madr; - DWORD new_ip; + UINT32 madr; + UINT32 new_ip; if (op >= 0xc0) { CPU_WORKCLOCK(7); new_ip = *(reg32_b20[op]); - PUSH0_32(CPU_EIP); - SET_EIP(new_ip); } else { CPU_WORKCLOCK(11); madr = calc_ea_dst(op); new_ip = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); - PUSH0_32(CPU_EIP); - SET_EIP(new_ip); } + PUSH0_32(CPU_EIP); + SET_EIP(new_ip); } void CALL16_Ap(void) { - WORD new_ip; - WORD new_cs; + UINT32 new_ip; + UINT16 new_cs; CPU_WORKCLOCK(13); GET_PCWORD(new_ip); @@ -913,8 +914,8 @@ CALL16_Ap(void) void CALL32_Ap(void) { - DWORD new_ip; - WORD new_cs; + UINT32 new_ip; + UINT16 new_cs; CPU_WORKCLOCK(13); GET_PCDWORD(new_ip); @@ -933,15 +934,15 @@ CALL32_Ap(void) } void -CALL16_Ep(DWORD op) +CALL16_Ep(UINT32 op) { - DWORD ad; - WORD new_ip; - WORD new_cs; + UINT32 ad; + UINT32 new_ip; + UINT16 new_cs; CPU_WORKCLOCK(16); if (op < 0xc0) { - ad = get_ea(op); + ad = calc_ea_dst(op); new_ip = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, ad); new_cs = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, ad + 2); if (!CPU_STAT_PM || CPU_STAT_VM86) { @@ -961,15 +962,15 @@ CALL16_Ep(DWORD op) } void -CALL32_Ep(DWORD op) +CALL32_Ep(UINT32 op) { - DWORD ad; - DWORD new_ip; - WORD new_cs; + UINT32 ad; + UINT32 new_ip; + UINT16 new_cs; CPU_WORKCLOCK(16); if (op < 0xc0) { - ad = get_ea(op); + ad = calc_ea_dst(op); new_ip = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, ad); new_cs = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, ad + 4); if (!CPU_STAT_PM || CPU_STAT_VM86) { @@ -994,7 +995,7 @@ CALL32_Ep(DWORD op) void RETnear16(void) { - WORD new_ip; + UINT32 new_ip; CPU_WORKCLOCK(11); POP0_16(new_ip); @@ -1004,7 +1005,7 @@ RETnear16(void) void RETnear32(void) { - DWORD new_ip; + UINT32 new_ip; CPU_WORKCLOCK(11); POP0_32(new_ip); @@ -1014,34 +1015,42 @@ RETnear32(void) void RETnear16_Iw(void) { - WORD new_ip; - WORD ad; + UINT32 new_ip; + UINT16 size; CPU_WORKCLOCK(11); - GET_PCWORD(ad); + GET_PCWORD(size); POP0_16(new_ip); SET_EIP(new_ip); - CPU_SP += ad; + if (!CPU_STAT_SS32) { + CPU_SP += size; + } else { + CPU_ESP += size; + } } void RETnear32_Iw(void) { - DWORD new_ip; - DWORD ad; + UINT32 new_ip; + UINT16 size; CPU_WORKCLOCK(11); - GET_PCDWORD(ad); + GET_PCWORD(size); POP0_32(new_ip); SET_EIP(new_ip); - CPU_ESP += ad; + if (!CPU_STAT_SS32) { + CPU_SP += size; + } else { + CPU_ESP += size; + } } void RETfar16(void) { - WORD new_ip; - WORD new_cs; + UINT32 new_ip; + UINT16 new_cs; CPU_WORKCLOCK(15); if (!CPU_STAT_PM || CPU_STAT_VM86) { @@ -1060,8 +1069,8 @@ RETfar16(void) void RETfar32(void) { - DWORD new_ip; - WORD new_cs; + UINT32 new_ip; + UINT32 new_cs; CPU_WORKCLOCK(15); if (!CPU_STAT_PM || CPU_STAT_VM86) { @@ -1069,7 +1078,7 @@ RETfar32(void) POP0_32(new_ip); POP0_32(new_cs); - CPU_SET_SEGREG(CPU_CS_INDEX, new_cs); + CPU_SET_SEGREG(CPU_CS_INDEX, (UINT16)new_cs); SET_EIP(new_ip); } else { /* Protected mode */ @@ -1080,95 +1089,84 @@ RETfar32(void) void RETfar16_Iw(void) { - WORD ad; - WORD new_ip; - WORD new_cs; + UINT32 new_ip; + UINT16 new_cs; + UINT16 size; CPU_WORKCLOCK(15); - GET_PCWORD(ad); + GET_PCWORD(size); if (!CPU_STAT_PM || CPU_STAT_VM86) { /* Real mode or VM86 mode */ POP0_16(new_ip); POP0_16(new_cs); - CPU_SP += ad; CPU_SET_SEGREG(CPU_CS_INDEX, new_cs); SET_EIP(new_ip); + + if (!CPU_STAT_SS32) { + CPU_SP += size; + } else { + CPU_ESP += size; + } } else { /* Protected mode */ - RETfar_pm(ad); + RETfar_pm(size); } } void RETfar32_Iw(void) { - DWORD ad; - DWORD new_ip; - WORD new_cs; + UINT32 new_ip; + UINT32 new_cs; + UINT16 size; CPU_WORKCLOCK(15); - GET_PCDWORD(ad); + GET_PCWORD(size); if (!CPU_STAT_PM || CPU_STAT_VM86) { /* Real mode or VM86 mode */ POP0_32(new_ip); POP0_32(new_cs); - CPU_ESP += ad; - CPU_SET_SEGREG(CPU_CS_INDEX, new_cs); + CPU_SET_SEGREG(CPU_CS_INDEX, (UINT16)new_cs); SET_EIP(new_ip); - } else { - /* Protected mode */ - RETfar_pm(ad); - } -} -void -IRET(void) -{ - WORD new_ip; - WORD flag; - WORD new_cs; - - CPU_WORKCLOCK(31); - if (!CPU_STAT_PM) { - /* Real mode */ - POP0_16(new_ip); - POP0_16(new_cs); - POP0_16(flag); - - CPU_FLAG = flag & 0x7fd5; - CPU_OV = CPU_FLAG & O_FLAG; - CPU_TRAP = (CPU_FLAG & (I_FLAG|T_FLAG)) == (I_FLAG|T_FLAG); - - CPU_SET_SEGREG(CPU_CS_INDEX, new_cs); - SET_EIP(new_ip); + if (!CPU_STAT_SS32) { + CPU_SP += size; + } else { + CPU_ESP += size; + } } else { /* Protected mode */ - IRET_pm(); + RETfar_pm(size); } - IRQCHECKTERM(); } void -IRETD(void) +IRET(void) { - DWORD new_ip; - DWORD flag; - WORD new_cs; + UINT32 new_ip; + UINT32 new_flags; + UINT32 mask; + UINT32 new_cs; - CPU_WORKCLOCK(31); if (!CPU_STAT_PM) { /* Real mode */ - POP0_32(new_ip); - POP0_32(new_cs); - POP0_32(flag); - - CPU_EFLAG = (flag & 0x00257fd5) | (REAL_EFLAGREG & 0x1a0000); - CPU_OV = CPU_FLAG & O_FLAG; - CPU_TRAP = (CPU_FLAG & (I_FLAG|T_FLAG)) == (I_FLAG|T_FLAG); + CPU_WORKCLOCK(22); + mask = I_FLAG|IOPL_FLAG; + if (!CPU_INST_OP32) { + POP0_16(new_ip); + POP0_16(new_cs); + POP0_16(new_flags); + } else { + POP0_32(new_ip); + POP0_32(new_cs); + POP0_32(new_flags); + mask |= RF_FLAG; + } + set_eflags(new_flags, mask); - CPU_SET_SEGREG(CPU_CS_INDEX, new_cs); + CPU_SET_SEGREG(CPU_CS_INDEX, (UINT16)new_cs); SET_EIP(new_ip); } else { /* Protected mode */ @@ -1184,7 +1182,7 @@ void INT1(void) { - CPU_WORKCLOCK(23); + CPU_WORKCLOCK(33); INTERRUPT(1, 1, 0, 0); } @@ -1192,7 +1190,7 @@ void INT3(void) { - CPU_WORKCLOCK(23); + CPU_WORKCLOCK(33); INTERRUPT(3, 2, 0, 0); } @@ -1201,19 +1199,19 @@ INTO(void) { if (!CPU_OV) { - CPU_WORKCLOCK(4); + CPU_WORKCLOCK(3); return; } - CPU_WORKCLOCK(24); + CPU_WORKCLOCK(35); INTERRUPT(4, 3, 0, 0); } void INT_Ib(void) { - BYTE vect; + UINT8 vect; - CPU_WORKCLOCK(23); + CPU_WORKCLOCK(37); if (!CPU_STAT_PM || !CPU_STAT_VM86 || (CPU_STAT_IOPL == CPU_IOPL3)) { GET_PCBYTE(vect); INTERRUPT(vect, -1, 0, 0); @@ -1225,8 +1223,8 @@ INT_Ib(void) void BOUND_GwMa(void) { - DWORD op, madr; - WORD reg; + UINT32 op, madr; + UINT16 reg; int vect; CPU_WORKCLOCK(13); @@ -1248,8 +1246,8 @@ BOUND_GwMa(void) void BOUND_GdMa(void) { - DWORD op, madr; - DWORD reg; + UINT32 op, madr; + UINT32 reg; int vect; CPU_WORKCLOCK(13); @@ -1272,10 +1270,13 @@ BOUND_GdMa(void) * STACK */ void -ENTER_IwIb(void) +ENTER16_IwIb(void) { - WORD dimsize; - BYTE level; + UINT32 sp, bp; + UINT32 size; + UINT32 val; + UINT16 dimsize; + UINT8 level; GET_PCWORD(dimsize); GET_PCBYTE(level); @@ -1283,29 +1284,19 @@ ENTER_IwIb(void) /* check stack room size */ if (CPU_STAT_PM) { - DWORD size = dimsize; - DWORD sp; - if (CPU_INST_OP32) { - size = (level + 1) * 4; + size = dimsize + (level + 1) * 2; + if (!CPU_STAT_SS32) { + sp = CPU_SP; } else { - size = (level + 1) * 2; - } - if (CPU_STAT_SS32) { sp = CPU_ESP; - } else { - sp = CPU_SP; } CHECK_STACK_PUSH(&CPU_STAT_SREG(CPU_SS_INDEX), sp, size); } - XPUSH0(CPU_EBP); + PUSH0_16(CPU_BP); if (level == 0) { /* enter level=0 */ CPU_WORKCLOCK(11); - if (!CPU_INST_OP32) { - CPU_BP = CPU_SP; - } else { - CPU_EBP = CPU_ESP; - } + CPU_BP = CPU_SP; if (!CPU_STAT_SS32) { CPU_SP -= dimsize; } else { @@ -1315,135 +1306,143 @@ ENTER_IwIb(void) --level; if (level == 0) { /* enter level=1 */ CPU_WORKCLOCK(15); - if (!CPU_INST_OP32) { - WORD tmp = CPU_SP; - PUSH0_16(tmp); - CPU_BP = tmp; + sp = CPU_SP; + PUSH0_16(sp); + CPU_BP = (UINT16)sp; + if (!CPU_STAT_SS32) { CPU_SP -= dimsize; } else { - DWORD tmp; - if (!CPU_STAT_SS32) { - tmp = CPU_SP; - REGPUSH0_32_16(tmp); - CPU_EBP = (WORD)tmp; - CPU_ESP -= dimsize; - } else { - tmp = CPU_ESP; - REGPUSH0_32(tmp); - CPU_EBP = tmp; - CPU_ESP -= dimsize; - } + CPU_ESP -= dimsize; } } else { /* enter level=2-31 */ CPU_WORKCLOCK(12 + level * 4); - if (!CPU_INST_OP32) { - WORD bp = CPU_BP; - WORD val; - + if (!CPU_STAT_SS32) { + bp = CPU_BP; CPU_BP = CPU_SP; - if (!CPU_STAT_SS32) { - while (level--) { - bp -= 2; - CPU_SP -= 2; - val = cpu_vmemoryread_w(CPU_SS_INDEX, bp); - cpu_vmemorywrite_w(CPU_SS_INDEX, CPU_SP, val); - } - REGPUSH0(CPU_BP); - CPU_SP -= dimsize; - } else { - while (level--) { - bp -= 2; - CPU_ESP -= 2; - val = cpu_vmemoryread_w(CPU_SS_INDEX, bp); - cpu_vmemorywrite_w(CPU_SS_INDEX, CPU_ESP, val); - } - REGPUSH0_16_32(CPU_EBP); - CPU_ESP -= dimsize; + while (level--) { + bp -= 2; + CPU_SP -= 2; + val = cpu_vmemoryread_w(CPU_SS_INDEX, bp); + cpu_vmemorywrite_w(CPU_SS_INDEX, CPU_SP, (UINT16)val); } + REGPUSH0(CPU_BP); + CPU_SP -= dimsize; } else { - DWORD ebp = CPU_EBP; - DWORD val; - - if (!CPU_STAT_SS32) { - CPU_EBP = CPU_SP; - while (level--) { - ebp -= 4; - CPU_SP -= 4; - val = cpu_vmemoryread_d(CPU_SS_INDEX, ebp); - cpu_vmemorywrite_d(CPU_SS_INDEX, CPU_SP, val); - } - REGPUSH0_32_16(CPU_EBP); - CPU_SP -= dimsize; - } else { - CPU_EBP = CPU_ESP; - while (level--) { - ebp -= 4; - CPU_ESP -= 4; - val = cpu_vmemoryread_d(CPU_SS_INDEX, ebp); - cpu_vmemorywrite(CPU_SS_INDEX, CPU_ESP, val); - } - REGPUSH0_32(CPU_EBP); - CPU_ESP -= dimsize; + bp = CPU_EBP; + CPU_BP = CPU_SP; + while (level--) { + bp -= 2; + CPU_ESP -= 2; + val = cpu_vmemoryread_w(CPU_SS_INDEX, bp); + cpu_vmemorywrite_w(CPU_SS_INDEX, CPU_ESP, (UINT16)val); } + REGPUSH0_16_32(CPU_BP); + CPU_ESP -= dimsize; } } } } void -LEAVE16(void) +ENTER32_IwIb(void) { - WORD bp; - DWORD sp, size; + UINT32 sp, bp; + UINT32 size; + UINT32 val; + UINT16 dimsize; + UINT8 level; - CPU_WORKCLOCK(5); + GET_PCWORD(dimsize); + GET_PCBYTE(level); + level &= 0x1f; + /* check stack room size */ if (CPU_STAT_PM) { - bp = CPU_BP; - if (!CPU_STAT_SS32) { + size = dimsize + (level + 1) * 4; + if (CPU_STAT_SS32) { + sp = CPU_ESP; + } else { sp = CPU_SP; - size = 2; + } + CHECK_STACK_PUSH(&CPU_STAT_SREG(CPU_SS_INDEX), sp, size); + } + + PUSH0_32(CPU_EBP); + if (level == 0) { /* enter level=0 */ + CPU_WORKCLOCK(11); + CPU_EBP = CPU_ESP; + if (!CPU_STAT_SS32) { + CPU_SP -= dimsize; } else { - sp = CPU_ESP; - size = 4; + CPU_ESP -= dimsize; } - if (bp < sp) { - ia32_panic("LEAVE16: bp < sp"); + } else { + --level; + if (level == 0) { /* enter level=1 */ + CPU_WORKCLOCK(15); + sp = CPU_ESP; + PUSH0_32(sp); + CPU_EBP = sp; + if (CPU_STAT_SS32) { + CPU_ESP -= dimsize; + } else { + CPU_SP -= dimsize; + } + } else { /* enter level=2-31 */ + CPU_WORKCLOCK(12 + level * 4); + if (CPU_STAT_SS32) { + bp = CPU_EBP; + CPU_EBP = CPU_ESP; + while (level--) { + bp -= 4; + CPU_ESP -= 4; + val = cpu_vmemoryread_d(CPU_SS_INDEX, bp); + cpu_vmemorywrite_d(CPU_SS_INDEX, CPU_ESP, val); + } + REGPUSH0_32(CPU_EBP); + CPU_ESP -= dimsize; + } else { + bp = CPU_BP; + CPU_EBP = CPU_ESP; + while (level--) { + bp -= 4; + CPU_SP -= 4; + val = cpu_vmemoryread_d(CPU_SS_INDEX, bp); + cpu_vmemorywrite_d(CPU_SS_INDEX, CPU_SP, val); + } + REGPUSH0_32_16(CPU_EBP); + CPU_SP -= dimsize; + } } - CHECK_STACK_PUSH(&CPU_STAT_SREG(CPU_SS_INDEX), sp, (bp - sp) + size); } - - CPU_SP = CPU_BP; - REGPOP0(CPU_BP); } void -LEAVE32(void) +LEAVE(void) { - DWORD bp, sp, size; + UINT32 sp, bp; - CPU_WORKCLOCK(5); + CPU_WORKCLOCK(4); if (CPU_STAT_PM) { - bp = CPU_EBP; - if (CPU_STAT_SS32) { - sp = CPU_ESP; - size = 4; - } else { + if (!CPU_STAT_SS32) { sp = CPU_SP; - size = 2; - } - if (bp < sp) { - ia32_panic("LEAVE32: bp < sp"); + bp = CPU_BP; + } else { + sp = CPU_ESP; + bp = CPU_EBP; } - CHECK_STACK_PUSH(&CPU_STAT_SREG(CPU_SS_INDEX), sp, (bp - sp) + size); + CHECK_STACK_POP(&CPU_STAT_SREG(CPU_SS_INDEX), sp, (bp-sp) + 2); } - if (CPU_STAT_SS32) { + if (!CPU_STAT_SS32) { + CPU_SP = CPU_BP; + } else { CPU_ESP = CPU_EBP; - REGPOP0_32(CPU_EBP); + } + if (!CPU_INST_OP32) { + REGPOP0(CPU_BP); } else { - CPU_SP = CPU_BP; - REGPOP0_32_16(CPU_EBP); + POP0_32(CPU_EBP); } }