Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
raspberrypi-kernel
提交
1c73ef66
R
raspberrypi-kernel
项目概览
openeuler
/
raspberrypi-kernel
通知
13
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
raspberrypi-kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
1c73ef66
编写于
11月 01, 2007
作者:
A
Avi Kivity
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
KVM: x86 emulator: Hoist modrm and abs decoding into separate functions
Signed-off-by:
N
Avi Kivity
<
avi@qumranet.com
>
上级
3b6fff19
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
177 addition
and
160 deletion
+177
-160
drivers/kvm/x86_emulate.c
drivers/kvm/x86_emulate.c
+177
-160
未找到文件。
drivers/kvm/x86_emulate.c
浏览文件 @
1c73ef66
...
...
@@ -548,14 +548,182 @@ static void decode_register_operand(struct operand *op,
op
->
orig_val
=
op
->
val
;
}
static
int
decode_modrm
(
struct
x86_emulate_ctxt
*
ctxt
,
struct
x86_emulate_ops
*
ops
)
{
struct
decode_cache
*
c
=
&
ctxt
->
decode
;
u8
sib
;
int
index_reg
=
0
,
base_reg
=
0
,
scale
,
rip_relative
=
0
;
int
rc
=
0
;
if
(
c
->
rex_prefix
)
{
c
->
modrm_reg
=
(
c
->
rex_prefix
&
4
)
<<
1
;
/* REX.R */
index_reg
=
(
c
->
rex_prefix
&
2
)
<<
2
;
/* REX.X */
c
->
modrm_rm
=
base_reg
=
(
c
->
rex_prefix
&
1
)
<<
3
;
/* REG.B */
}
c
->
modrm
=
insn_fetch
(
u8
,
1
,
c
->
eip
);
c
->
modrm_mod
|=
(
c
->
modrm
&
0xc0
)
>>
6
;
c
->
modrm_reg
|=
(
c
->
modrm
&
0x38
)
>>
3
;
c
->
modrm_rm
|=
(
c
->
modrm
&
0x07
);
c
->
modrm_ea
=
0
;
c
->
use_modrm_ea
=
1
;
if
(
c
->
modrm_mod
==
3
)
{
c
->
modrm_val
=
*
(
unsigned
long
*
)
decode_register
(
c
->
modrm_rm
,
c
->
regs
,
c
->
d
&
ByteOp
);
return
rc
;
}
if
(
c
->
ad_bytes
==
2
)
{
unsigned
bx
=
c
->
regs
[
VCPU_REGS_RBX
];
unsigned
bp
=
c
->
regs
[
VCPU_REGS_RBP
];
unsigned
si
=
c
->
regs
[
VCPU_REGS_RSI
];
unsigned
di
=
c
->
regs
[
VCPU_REGS_RDI
];
/* 16-bit ModR/M decode. */
switch
(
c
->
modrm_mod
)
{
case
0
:
if
(
c
->
modrm_rm
==
6
)
c
->
modrm_ea
+=
insn_fetch
(
u16
,
2
,
c
->
eip
);
break
;
case
1
:
c
->
modrm_ea
+=
insn_fetch
(
s8
,
1
,
c
->
eip
);
break
;
case
2
:
c
->
modrm_ea
+=
insn_fetch
(
u16
,
2
,
c
->
eip
);
break
;
}
switch
(
c
->
modrm_rm
)
{
case
0
:
c
->
modrm_ea
+=
bx
+
si
;
break
;
case
1
:
c
->
modrm_ea
+=
bx
+
di
;
break
;
case
2
:
c
->
modrm_ea
+=
bp
+
si
;
break
;
case
3
:
c
->
modrm_ea
+=
bp
+
di
;
break
;
case
4
:
c
->
modrm_ea
+=
si
;
break
;
case
5
:
c
->
modrm_ea
+=
di
;
break
;
case
6
:
if
(
c
->
modrm_mod
!=
0
)
c
->
modrm_ea
+=
bp
;
break
;
case
7
:
c
->
modrm_ea
+=
bx
;
break
;
}
if
(
c
->
modrm_rm
==
2
||
c
->
modrm_rm
==
3
||
(
c
->
modrm_rm
==
6
&&
c
->
modrm_mod
!=
0
))
if
(
!
c
->
override_base
)
c
->
override_base
=
&
ctxt
->
ss_base
;
c
->
modrm_ea
=
(
u16
)
c
->
modrm_ea
;
}
else
{
/* 32/64-bit ModR/M decode. */
switch
(
c
->
modrm_rm
)
{
case
4
:
case
12
:
sib
=
insn_fetch
(
u8
,
1
,
c
->
eip
);
index_reg
|=
(
sib
>>
3
)
&
7
;
base_reg
|=
sib
&
7
;
scale
=
sib
>>
6
;
switch
(
base_reg
)
{
case
5
:
if
(
c
->
modrm_mod
!=
0
)
c
->
modrm_ea
+=
c
->
regs
[
base_reg
];
else
c
->
modrm_ea
+=
insn_fetch
(
s32
,
4
,
c
->
eip
);
break
;
default:
c
->
modrm_ea
+=
c
->
regs
[
base_reg
];
}
switch
(
index_reg
)
{
case
4
:
break
;
default:
c
->
modrm_ea
+=
c
->
regs
[
index_reg
]
<<
scale
;
}
break
;
case
5
:
if
(
c
->
modrm_mod
!=
0
)
c
->
modrm_ea
+=
c
->
regs
[
c
->
modrm_rm
];
else
if
(
ctxt
->
mode
==
X86EMUL_MODE_PROT64
)
rip_relative
=
1
;
break
;
default:
c
->
modrm_ea
+=
c
->
regs
[
c
->
modrm_rm
];
break
;
}
switch
(
c
->
modrm_mod
)
{
case
0
:
if
(
c
->
modrm_rm
==
5
)
c
->
modrm_ea
+=
insn_fetch
(
s32
,
4
,
c
->
eip
);
break
;
case
1
:
c
->
modrm_ea
+=
insn_fetch
(
s8
,
1
,
c
->
eip
);
break
;
case
2
:
c
->
modrm_ea
+=
insn_fetch
(
s32
,
4
,
c
->
eip
);
break
;
}
}
if
(
rip_relative
)
{
c
->
modrm_ea
+=
c
->
eip
;
switch
(
c
->
d
&
SrcMask
)
{
case
SrcImmByte
:
c
->
modrm_ea
+=
1
;
break
;
case
SrcImm
:
if
(
c
->
d
&
ByteOp
)
c
->
modrm_ea
+=
1
;
else
if
(
c
->
op_bytes
==
8
)
c
->
modrm_ea
+=
4
;
else
c
->
modrm_ea
+=
c
->
op_bytes
;
}
}
done:
return
rc
;
}
static
int
decode_abs
(
struct
x86_emulate_ctxt
*
ctxt
,
struct
x86_emulate_ops
*
ops
)
{
struct
decode_cache
*
c
=
&
ctxt
->
decode
;
int
rc
=
0
;
switch
(
c
->
ad_bytes
)
{
case
2
:
c
->
modrm_ea
=
insn_fetch
(
u16
,
2
,
c
->
eip
);
break
;
case
4
:
c
->
modrm_ea
=
insn_fetch
(
u32
,
4
,
c
->
eip
);
break
;
case
8
:
c
->
modrm_ea
=
insn_fetch
(
u64
,
8
,
c
->
eip
);
break
;
}
done:
return
rc
;
}
int
x86_decode_insn
(
struct
x86_emulate_ctxt
*
ctxt
,
struct
x86_emulate_ops
*
ops
)
{
struct
decode_cache
*
c
=
&
ctxt
->
decode
;
u8
sib
;
int
rc
=
0
;
int
mode
=
ctxt
->
mode
;
int
index_reg
=
0
,
base_reg
=
0
,
scale
,
rip_relative
=
0
;
/* Shadow copy of register state. Committed on successful emulation. */
...
...
@@ -637,13 +805,9 @@ x86_decode_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
done_prefixes:
/* REX prefix. */
if
(
c
->
rex_prefix
)
{
if
(
c
->
rex_prefix
)
if
(
c
->
rex_prefix
&
8
)
c
->
op_bytes
=
8
;
/* REX.W */
c
->
modrm_reg
=
(
c
->
rex_prefix
&
4
)
<<
1
;
/* REX.R */
index_reg
=
(
c
->
rex_prefix
&
2
)
<<
2
;
/* REX.X */
c
->
modrm_rm
=
base_reg
=
(
c
->
rex_prefix
&
1
)
<<
3
;
/* REG.B */
}
/* Opcode byte(s). */
c
->
d
=
opcode_table
[
c
->
b
];
...
...
@@ -663,159 +827,12 @@ x86_decode_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
}
/* ModRM and SIB bytes. */
if
(
c
->
d
&
ModRM
)
{
c
->
modrm
=
insn_fetch
(
u8
,
1
,
c
->
eip
);
c
->
modrm_mod
|=
(
c
->
modrm
&
0xc0
)
>>
6
;
c
->
modrm_reg
|=
(
c
->
modrm
&
0x38
)
>>
3
;
c
->
modrm_rm
|=
(
c
->
modrm
&
0x07
);
c
->
modrm_ea
=
0
;
c
->
use_modrm_ea
=
1
;
if
(
c
->
modrm_mod
==
3
)
{
c
->
modrm_val
=
*
(
unsigned
long
*
)
decode_register
(
c
->
modrm_rm
,
c
->
regs
,
c
->
d
&
ByteOp
);
goto
modrm_done
;
}
if
(
c
->
ad_bytes
==
2
)
{
unsigned
bx
=
c
->
regs
[
VCPU_REGS_RBX
];
unsigned
bp
=
c
->
regs
[
VCPU_REGS_RBP
];
unsigned
si
=
c
->
regs
[
VCPU_REGS_RSI
];
unsigned
di
=
c
->
regs
[
VCPU_REGS_RDI
];
/* 16-bit ModR/M decode. */
switch
(
c
->
modrm_mod
)
{
case
0
:
if
(
c
->
modrm_rm
==
6
)
c
->
modrm_ea
+=
insn_fetch
(
u16
,
2
,
c
->
eip
);
break
;
case
1
:
c
->
modrm_ea
+=
insn_fetch
(
s8
,
1
,
c
->
eip
);
break
;
case
2
:
c
->
modrm_ea
+=
insn_fetch
(
u16
,
2
,
c
->
eip
);
break
;
}
switch
(
c
->
modrm_rm
)
{
case
0
:
c
->
modrm_ea
+=
bx
+
si
;
break
;
case
1
:
c
->
modrm_ea
+=
bx
+
di
;
break
;
case
2
:
c
->
modrm_ea
+=
bp
+
si
;
break
;
case
3
:
c
->
modrm_ea
+=
bp
+
di
;
break
;
case
4
:
c
->
modrm_ea
+=
si
;
break
;
case
5
:
c
->
modrm_ea
+=
di
;
break
;
case
6
:
if
(
c
->
modrm_mod
!=
0
)
c
->
modrm_ea
+=
bp
;
break
;
case
7
:
c
->
modrm_ea
+=
bx
;
break
;
}
if
(
c
->
modrm_rm
==
2
||
c
->
modrm_rm
==
3
||
(
c
->
modrm_rm
==
6
&&
c
->
modrm_mod
!=
0
))
if
(
!
c
->
override_base
)
c
->
override_base
=
&
ctxt
->
ss_base
;
c
->
modrm_ea
=
(
u16
)
c
->
modrm_ea
;
}
else
{
/* 32/64-bit ModR/M decode. */
switch
(
c
->
modrm_rm
)
{
case
4
:
case
12
:
sib
=
insn_fetch
(
u8
,
1
,
c
->
eip
);
index_reg
|=
(
sib
>>
3
)
&
7
;
base_reg
|=
sib
&
7
;
scale
=
sib
>>
6
;
switch
(
base_reg
)
{
case
5
:
if
(
c
->
modrm_mod
!=
0
)
c
->
modrm_ea
+=
c
->
regs
[
base_reg
];
else
c
->
modrm_ea
+=
insn_fetch
(
s32
,
4
,
c
->
eip
);
break
;
default:
c
->
modrm_ea
+=
c
->
regs
[
base_reg
];
}
switch
(
index_reg
)
{
case
4
:
break
;
default:
c
->
modrm_ea
+=
c
->
regs
[
index_reg
]
<<
scale
;
}
break
;
case
5
:
if
(
c
->
modrm_mod
!=
0
)
c
->
modrm_ea
+=
c
->
regs
[
c
->
modrm_rm
];
else
if
(
mode
==
X86EMUL_MODE_PROT64
)
rip_relative
=
1
;
break
;
default:
c
->
modrm_ea
+=
c
->
regs
[
c
->
modrm_rm
];
break
;
}
switch
(
c
->
modrm_mod
)
{
case
0
:
if
(
c
->
modrm_rm
==
5
)
c
->
modrm_ea
+=
insn_fetch
(
s32
,
4
,
c
->
eip
);
break
;
case
1
:
c
->
modrm_ea
+=
insn_fetch
(
s8
,
1
,
c
->
eip
);
break
;
case
2
:
c
->
modrm_ea
+=
insn_fetch
(
s32
,
4
,
c
->
eip
);
break
;
}
}
if
(
rip_relative
)
{
c
->
modrm_ea
+=
c
->
eip
;
switch
(
c
->
d
&
SrcMask
)
{
case
SrcImmByte
:
c
->
modrm_ea
+=
1
;
break
;
case
SrcImm
:
if
(
c
->
d
&
ByteOp
)
c
->
modrm_ea
+=
1
;
else
if
(
c
->
op_bytes
==
8
)
c
->
modrm_ea
+=
4
;
else
c
->
modrm_ea
+=
c
->
op_bytes
;
}
}
modrm_done:
;
}
else
if
(
c
->
d
&
MemAbs
)
{
switch
(
c
->
ad_bytes
)
{
case
2
:
c
->
modrm_ea
=
insn_fetch
(
u16
,
2
,
c
->
eip
);
break
;
case
4
:
c
->
modrm_ea
=
insn_fetch
(
u32
,
4
,
c
->
eip
);
break
;
case
8
:
c
->
modrm_ea
=
insn_fetch
(
u64
,
8
,
c
->
eip
);
break
;
}
}
if
(
c
->
d
&
ModRM
)
rc
=
decode_modrm
(
ctxt
,
ops
);
else
if
(
c
->
d
&
MemAbs
)
rc
=
decode_abs
(
ctxt
,
ops
);
if
(
rc
)
goto
done
;
if
(
!
c
->
override_base
)
c
->
override_base
=
&
ctxt
->
ds_base
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录