[libcpu] [421] x86: Decoding for opcode 0xc1 ("shift group 2")

8 views
Skip to first unread message

lib...@gh11.de

unread,
Apr 25, 2010, 8:20:10 AM4/25/10
to lib...@googlegroups.com
Revision
421
Author
penberg
Date
2010-04-25 05:20:07 -0700 (Sun, 25 Apr 2010)

Log Message

x86: Decoding for opcode 0xc1 ("shift group 2")

Opcode 0xc1 is the full width version of opcode 0xc0.

Signed-off-by: Pekka Enberg <pen...@cs.helsinki.fi>

Modified Paths

Diff

Modified: trunk/arch/x86/x86_decode.cpp (420 => 421)


--- trunk/arch/x86/x86_decode.cpp	2010-04-25 11:56:30 UTC (rev 420)
+++ trunk/arch/x86/x86_decode.cpp	2010-04-25 12:20:07 UTC (rev 421)
@@ -206,8 +206,8 @@
 	/*[0xBD]*/	INSTR_MOV | ADDMODE_IMM_REG | WIDTH_FULL,
 	/*[0xBE]*/	INSTR_MOV | ADDMODE_IMM_REG | WIDTH_FULL,
 	/*[0xBF]*/	INSTR_MOV | ADDMODE_IMM_REG | WIDTH_FULL,
-	/*[0xC0]*/	INSTR_SHIFT_GRP2 | ADDMODE_IMM_RM | WIDTH_BYTE,
-	/*[0xC1]*/	0,
+	/*[0xC0]*/	INSTR_SHIFT_GRP2 | ADDMODE_IMM8_RM | WIDTH_BYTE,
+	/*[0xC0]*/	INSTR_SHIFT_GRP2 | ADDMODE_IMM8_RM | WIDTH_FULL,
 	/*[0xC2]*/	0,
 	/*[0xC3]*/	INSTR_RET | ADDMODE_IMPLIED,
 	/*[0xC4]*/	0,
@@ -347,6 +347,7 @@
 	case SRC_NONE:
 		break;
 	case SRC_IMM:
+	case SRC_IMM8:
 		operand->type	= OP_IMM;
 		operand->imm	= instr->imm_data;
 		break;
@@ -371,25 +372,46 @@
 }
 
 static void
-decode_imm(struct x86_instr *instr, uint8_t* RAM, addr_t *pc)
+decode_imm_full(struct x86_instr *instr, uint8_t* RAM, addr_t *pc)
 {
 	addr_t new_pc = *pc;
 
+	uint8_t imm_lo = RAM[new_pc++];
+	uint8_t imm_hi = RAM[new_pc++];
+
+	instr->imm_data	= (uint16_t)((imm_hi << 8) | imm_lo);
+	instr->nr_bytes	+= 2;
+
+	*pc = new_pc;
+}
+
+static void
+decode_imm_byte(struct x86_instr *instr, uint8_t* RAM, addr_t *pc)
+{
+	addr_t new_pc = *pc;
+
+	instr->imm_data	= (uint8_t)RAM[new_pc++];
+	instr->nr_bytes	+= 1;
+
+	*pc = new_pc;
+}
+
+static void
+decode_imm(struct x86_instr *instr, uint8_t* RAM, addr_t *pc)
+{
+	if (instr->flags & SRC_IMM8) {
+		decode_imm_byte(instr, RAM, pc);
+		return;
+	}
+
 	switch (instr->flags & WIDTH_MASK) {
-	case WIDTH_FULL: {
-		uint8_t imm_lo = RAM[new_pc++];
-		uint8_t imm_hi = RAM[new_pc++];
-
-		instr->imm_data	= (uint16_t)((imm_hi << 8) | imm_lo);
-		instr->nr_bytes	+= 2;
+	case WIDTH_FULL:
+		decode_imm_full(instr, RAM, pc);
 		break;
-	}
 	case WIDTH_BYTE:
-		instr->imm_data	= (uint8_t)RAM[new_pc++];
-		instr->nr_bytes	+= 1;
+		decode_imm_byte(instr, RAM, pc);
 		break;
 	}
-	*pc = new_pc;
 }
 
 static void
@@ -509,7 +531,7 @@
 	if (instr->flags & MEM_DISP_MASK)
 		decode_disp(instr, RAM, &pc);
 
-	if (instr->flags & SRC_IMM)
+	if (instr->flags & IMM_MASK)
 		decode_imm(instr, RAM, &pc);
 
 	decode_src_operand(instr);

Modified: trunk/arch/x86/x86_decode.h (420 => 421)


--- trunk/arch/x86/x86_decode.h	2010-04-25 11:56:30 UTC (rev 420)
+++ trunk/arch/x86/x86_decode.h	2010-04-25 12:20:07 UTC (rev 421)
@@ -50,21 +50,25 @@
 
 	/* Source operand */
 	SRC_NONE		= (1U << 12),
+
 	SRC_IMM			= (1U << 13),
-	SRC_REG			= (1U << 14),
-	SRC_ACC			= (1U << 15),
-	SRC_MEM			= (1U << 16),
-	SRC_MEM_DISP_BYTE	= (1U << 17),
-	SRC_MEM_DISP_FULL	= (1U << 18),
-	SRC_MASK		= SRC_NONE|SRC_IMM|SRC_REG|SRC_ACC|SRC_MEM|SRC_MEM_DISP_BYTE|SRC_MEM_DISP_FULL,
+	SRC_IMM8		= (1U << 14),
+	IMM_MASK		= SRC_IMM|SRC_IMM8,
 
+	SRC_REG			= (1U << 15),
+	SRC_ACC			= (1U << 16),
+	SRC_MEM			= (1U << 17),
+	SRC_MEM_DISP_BYTE	= (1U << 18),
+	SRC_MEM_DISP_FULL	= (1U << 19),
+	SRC_MASK		= SRC_NONE|SRC_IMM|SRC_IMM8|SRC_REG|SRC_ACC|SRC_MEM|SRC_MEM_DISP_BYTE|SRC_MEM_DISP_FULL,
+
 	/* Destination operand */
-	DST_NONE		= (1U << 19),
-	DST_REG			= (1U << 20),
-	DST_ACC			= (1U << 21),	/* AL/AX */
-	DST_MEM			= (1U << 22),
-	DST_MEM_DISP_BYTE	= (1U << 23),	/* 8 bits */
-	DST_MEM_DISP_FULL	= (1U << 24),	/* 16 bits or 32 bits */
+	DST_NONE		= (1U << 20),
+	DST_REG			= (1U << 21),
+	DST_ACC			= (1U << 22),	/* AL/AX */
+	DST_MEM			= (1U << 23),
+	DST_MEM_DISP_BYTE	= (1U << 24),	/* 8 bits */
+	DST_MEM_DISP_FULL	= (1U << 25),	/* 16 bits or 32 bits */
 	DST_MASK		= DST_NONE|DST_REG|DST_ACC|DST_MEM|DST_MEM_DISP_BYTE|DST_MEM_DISP_FULL,
 
 	MEM_DISP_MASK		= SRC_MEM_DISP_BYTE|SRC_MEM_DISP_FULL|DST_MEM_DISP_BYTE|DST_MEM_DISP_FULL,
@@ -79,7 +83,7 @@
 	ADDMODE_IMM		= SRC_IMM|DST_NONE,		/* immediate operand */
 	ADDMODE_IMM_ACC		= SRC_IMM|DST_ACC,		/* immediate -> AL/AX */
 	ADDMODE_IMM_REG		= SRC_IMM|DST_REG,		/* immediate -> register */
-	ADDMODE_IMM_RM		= SRC_IMM|MOD_RM|DIR_REVERSED,	/* immediate -> register/memory */
+	ADDMODE_IMM8_RM		= SRC_IMM8|MOD_RM|DIR_REVERSED,	/* immediate -> register/memory */
 	ADDMODE_IMPLIED		= SRC_NONE|DST_NONE,		/* no operands */
 	ADDMODE_MEM_ACC		= SRC_ACC|DST_MEM,		/* memory -> AL/AX */
 	ADDMODE_REG		= SRC_REG|DST_NONE,		/* register */

Modified: trunk/test/bin/x86/i8086/i8086.S (420 => 421)


--- trunk/test/bin/x86/i8086/i8086.S	2010-04-25 11:56:30 UTC (rev 420)
+++ trunk/test/bin/x86/i8086/i8086.S	2010-04-25 12:20:07 UTC (rev 421)
@@ -364,7 +364,7 @@
 	xchgw %si, %ax
 	xchgw %di, %ax
 
-	# 0xc0
+	# 0xc0 /digit ("shift group 2")
 	rolb $0x00, %al
 	rolb $0xff, %bh
 
@@ -387,5 +387,28 @@
 	shrb $0x00, %al
 	shrb $0xff, %bh
 
+	# 0xc1 /digit ("shift group 2")
+	rolw $0x00, %ax
+	rolw $0xff, %bx
+
+	rorw $0x00, %ax
+	rorw $0xff, %bx
+
+	rclw $0x00, %ax
+	rclw $0xff, %bx
+
+	rcrw $0x00, %ax
+	rcrw $0xff, %bx
+
+	sarw $0x00, %ax
+	sarw $0xff, %bx
+
+	# The sal and shl instructions perform the same operation.
+	shlw $0x00, %ax
+	shlw $0xff, %bx
+
+	shrw $0x00, %ax
+	shrw $0xff, %bx
+
 	# 0xd7
 	xlat

Modified: trunk/test/bin/x86/i8086/i8086.bin


(Binary files differ)


 
--
Subscription settings: http://groups.google.com/group/libcpu/subscribe?hl=en
Reply all
Reply to author
Forward
0 new messages