FreeBSD/sys/contrib/x86emu/x86emu.c
/*
 * PARAMETERS:
 * rm	- RM value to decode
 * 
 * RETURNS:
 * Offset in memory for the address decoding
 * 
 * REMARKS:
 * Return the offset given by mod=00, mod=01 or mod=10 addressing.
 * Also enables the decoding of instructions.
 */
rm   - RM value to decode

Offset in memory for the address decoding

Return the offset given by mod=00, mod=01 or mod=10 addressing.
Also enables the decoding of instructions.
rm - RM value to decode Offset in memory for the address decoding Return the offset given by mod = 00 mod = 01 or mod = 10 addressing . Also enables the decoding of instructions .
static uint32_t
decode_rl_address(struct x86emu *emu)
{
	if (emu->x86.mode & SYSMODE_PREFIX_ADDR) {
		uint32_t offset, sib;
		switch (emu->cur_rl) {
		case 0:
			offset = emu->x86.R_EAX;
			break;
		case 1:
			offset = emu->x86.R_ECX;
			break;
		case 2:
			offset = emu->x86.R_EDX;
			break;
		case 3:
			offset = emu->x86.R_EBX;
			break;
		case 4:
			sib = fetch_byte_imm(emu);
			offset = decode_sib_address(emu, sib, 0);
			break;
		case 5:
			if (emu->cur_mod == 0) {
				offset = fetch_long_imm(emu);
			} else {
				emu->x86.mode |= SYSMODE_SEG_DS_SS;
				offset = emu->x86.R_EBP;
			}
			break;
		case 6:
			offset = emu->x86.R_ESI;
			break;
		case 7:
			offset = emu->x86.R_EDI;
			break;
		default:
			x86emu_halt_sys(emu);
		}
		if (emu->cur_mod == 1)
			offset += (int8_t)fetch_byte_imm(emu);
		else if (emu->cur_mod == 2)
			offset += fetch_long_imm(emu);
		return offset;
	} else {
		uint16_t offset;
		switch (emu->cur_rl) {
		case 0:
			offset = emu->x86.R_BX + emu->x86.R_SI;
			break;
		case 1:
			offset = emu->x86.R_BX + emu->x86.R_DI;
			break;
		case 2:
			emu->x86.mode |= SYSMODE_SEG_DS_SS;
			offset = emu->x86.R_BP + emu->x86.R_SI;
			break;
		case 3:
			emu->x86.mode |= SYSMODE_SEG_DS_SS;
			offset = emu->x86.R_BP + emu->x86.R_DI;
			break;
		case 4:
			offset = emu->x86.R_SI;
			break;
		case 5:
			offset = emu->x86.R_DI;
			break;
		case 6:
			if (emu->cur_mod == 0) {
				offset = fetch_word_imm(emu);
			} else {
				emu->x86.mode |= SYSMODE_SEG_DS_SS;
				offset = emu->x86.R_BP;
			}
			break;
		case 7:
			offset = emu->x86.R_BX;
			break;
		default:
			x86emu_halt_sys(emu);
		}
		if (emu->cur_mod == 1)
			offset += (int8_t)fetch_byte_imm(emu);
		else if (emu->cur_mod == 2)
			offset += fetch_word_imm(emu);
		return offset;
	}
}
static uint32_t decode_rl_address ( struct x86emu * emu ) { if ( emu -> x86 . mode & SYSMODE_PREFIX_ADDR ) { uint32_t offset , sib ; switch ( emu -> cur_rl ) { case 0 : offset = emu -> x86 . R_EAX ; break ; case 1 : offset = emu -> x86 . R_ECX ; break ; case 2 : offset = emu -> x86 . R_EDX ; break ; case 3 : offset = emu -> x86 . R_EBX ; break ; case 4 : sib = fetch_byte_imm ( emu ) ; offset = decode_sib_address ( emu , sib , 0 ) ; break ; case 5 : if ( emu -> cur_mod == 0 ) { offset = fetch_long_imm ( emu ) ; } else { emu -> x86 . mode |= SYSMODE_SEG_DS_SS ; offset = emu -> x86 . R_EBP ; } break ; case 6 : offset = emu -> x86 . R_ESI ; break ; case 7 : offset = emu -> x86 . R_EDI ; break ; default : x86emu_halt_sys ( emu ) ; } if ( emu -> cur_mod == 1 ) offset += ( int8_t ) fetch_byte_imm ( emu ) ; else if ( emu -> cur_mod == 2 ) offset += fetch_long_imm ( emu ) ; return offset ; } else { uint16_t offset ; switch ( emu -> cur_rl ) { case 0 : offset = emu -> x86 . R_BX + emu -> x86 . R_SI ; break ; case 1 : offset = emu -> x86 . R_BX + emu -> x86 . R_DI ; break ; case 2 : emu -> x86 . mode |= SYSMODE_SEG_DS_SS ; offset = emu -> x86 . R_BP + emu -> x86 . R_SI ; break ; case 3 : emu -> x86 . mode |= SYSMODE_SEG_DS_SS ; offset = emu -> x86 . R_BP + emu -> x86 . R_DI ; break ; case 4 : offset = emu -> x86 . R_SI ; break ; case 5 : offset = emu -> x86 . R_DI ; break ; case 6 : if ( emu -> cur_mod == 0 ) { offset = fetch_word_imm ( emu ) ; } else { emu -> x86 . mode |= SYSMODE_SEG_DS_SS ; offset = emu -> x86 . R_BP ; } break ; case 7 : offset = emu -> x86 . R_BX ; break ; default : x86emu_halt_sys ( emu ) ; } if ( emu -> cur_mod == 1 ) offset += ( int8_t ) fetch_byte_imm ( emu ) ; else if ( emu -> cur_mod == 2 ) offset += fetch_word_imm ( emu ) ; return offset ; } }
PARAMETERS:
 rm   - RM value to decode
PARAMETERS : rm - RM value to decode
/* 32-bit addressing */ /* 16-bit addressing */