Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
qemu
提交
e1b5a5ed
Q
qemu
项目概览
openeuler
/
qemu
通知
10
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
Q
qemu
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
e1b5a5ed
编写于
10月 09, 2017
作者:
R
Richard Henderson
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
target/hppa: Implement the system mask instructions
Signed-off-by:
N
Richard Henderson
<
richard.henderson@linaro.org
>
上级
3d68ee7b
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
113 addition
and
1 deletion
+113
-1
target/hppa/helper.h
target/hppa/helper.h
+4
-0
target/hppa/op_helper.c
target/hppa/op_helper.c
+14
-0
target/hppa/translate.c
target/hppa/translate.c
+95
-1
未找到文件。
target/hppa/helper.h
浏览文件 @
e1b5a5ed
...
...
@@ -76,3 +76,7 @@ DEF_HELPER_FLAGS_4(fmpyfadd_s, TCG_CALL_NO_RWG, i32, env, i32, i32, i32)
DEF_HELPER_FLAGS_4
(
fmpynfadd_s
,
TCG_CALL_NO_RWG
,
i32
,
env
,
i32
,
i32
,
i32
)
DEF_HELPER_FLAGS_4
(
fmpyfadd_d
,
TCG_CALL_NO_RWG
,
i64
,
env
,
i64
,
i64
,
i64
)
DEF_HELPER_FLAGS_4
(
fmpynfadd_d
,
TCG_CALL_NO_RWG
,
i64
,
env
,
i64
,
i64
,
i64
)
#ifndef CONFIG_USER_ONLY
DEF_HELPER_FLAGS_2
(
swap_system_mask
,
TCG_CALL_NO_RWG
,
tr
,
env
,
tr
)
#endif
target/hppa/op_helper.c
浏览文件 @
e1b5a5ed
...
...
@@ -601,3 +601,17 @@ float64 HELPER(fmpynfadd_d)(CPUHPPAState *env, float64 a, float64 b, float64 c)
update_fr0_op
(
env
,
GETPC
());
return
ret
;
}
#ifndef CONFIG_USER_ONLY
target_ureg
HELPER
(
swap_system_mask
)(
CPUHPPAState
*
env
,
target_ureg
nsm
)
{
target_ulong
psw
=
env
->
psw
;
/* ??? On second reading this condition simply seems
to be undefined rather than a diagnosed trap. */
if
(
nsm
&
~
psw
&
PSW_Q
)
{
dynexcp
(
env
,
EXCP_ILL
,
GETPC
());
}
env
->
psw
=
(
psw
&
~
PSW_SM
)
|
(
nsm
&
PSW_SM
);
return
psw
&
PSW_SM
;
}
#endif
target/hppa/translate.c
浏览文件 @
e1b5a5ed
...
...
@@ -299,6 +299,10 @@ typedef struct DisasContext {
updated the iaq for the next instruction to be executed. */
#define DISAS_IAQ_N_STALE DISAS_TARGET_1
/* Similarly, but we want to return to the main loop immediately
to recognize unmasked interrupts. */
#define DISAS_IAQ_N_STALE_EXIT DISAS_TARGET_2
typedef
struct
DisasInsn
{
uint32_t
insn
,
mask
;
DisasJumpType
(
*
trans
)(
DisasContext
*
ctx
,
uint32_t
insn
,
...
...
@@ -697,6 +701,14 @@ static DisasJumpType gen_illegal(DisasContext *ctx)
return
nullify_end
(
ctx
,
gen_excp
(
ctx
,
EXCP_ILL
));
}
#define CHECK_MOST_PRIVILEGED(EXCP) \
do { \
if (ctx->privilege != 0) { \
nullify_over(ctx); \
return nullify_end(ctx, gen_excp(ctx, EXCP)); \
} \
} while (0)
static
bool
use_goto_tb
(
DisasContext
*
ctx
,
target_ureg
dest
)
{
/* Suppress goto_tb in the case of single-steping and IO. */
...
...
@@ -1982,6 +1994,79 @@ static DisasJumpType trans_ldsid(DisasContext *ctx, uint32_t insn,
return
DISAS_NEXT
;
}
#ifndef CONFIG_USER_ONLY
/* Note that ssm/rsm instructions number PSW_W and PSW_E differently. */
static
target_ureg
extract_sm_imm
(
uint32_t
insn
)
{
target_ureg
val
=
extract32
(
insn
,
16
,
10
);
if
(
val
&
PSW_SM_E
)
{
val
=
(
val
&
~
PSW_SM_E
)
|
PSW_E
;
}
if
(
val
&
PSW_SM_W
)
{
val
=
(
val
&
~
PSW_SM_W
)
|
PSW_W
;
}
return
val
;
}
static
DisasJumpType
trans_rsm
(
DisasContext
*
ctx
,
uint32_t
insn
,
const
DisasInsn
*
di
)
{
unsigned
rt
=
extract32
(
insn
,
0
,
5
);
target_ureg
sm
=
extract_sm_imm
(
insn
);
TCGv_reg
tmp
;
CHECK_MOST_PRIVILEGED
(
EXCP_PRIV_OPR
);
nullify_over
(
ctx
);
tmp
=
get_temp
(
ctx
);
tcg_gen_ld_reg
(
tmp
,
cpu_env
,
offsetof
(
CPUHPPAState
,
psw
));
tcg_gen_andi_reg
(
tmp
,
tmp
,
~
sm
);
gen_helper_swap_system_mask
(
tmp
,
cpu_env
,
tmp
);
save_gpr
(
ctx
,
rt
,
tmp
);
/* Exit the TB to recognize new interrupts, e.g. PSW_M. */
return
nullify_end
(
ctx
,
DISAS_IAQ_N_STALE_EXIT
);
}
static
DisasJumpType
trans_ssm
(
DisasContext
*
ctx
,
uint32_t
insn
,
const
DisasInsn
*
di
)
{
unsigned
rt
=
extract32
(
insn
,
0
,
5
);
target_ureg
sm
=
extract_sm_imm
(
insn
);
TCGv_reg
tmp
;
CHECK_MOST_PRIVILEGED
(
EXCP_PRIV_OPR
);
nullify_over
(
ctx
);
tmp
=
get_temp
(
ctx
);
tcg_gen_ld_reg
(
tmp
,
cpu_env
,
offsetof
(
CPUHPPAState
,
psw
));
tcg_gen_ori_reg
(
tmp
,
tmp
,
sm
);
gen_helper_swap_system_mask
(
tmp
,
cpu_env
,
tmp
);
save_gpr
(
ctx
,
rt
,
tmp
);
/* Exit the TB to recognize new interrupts, e.g. PSW_I. */
return
nullify_end
(
ctx
,
DISAS_IAQ_N_STALE_EXIT
);
}
static
DisasJumpType
trans_mtsm
(
DisasContext
*
ctx
,
uint32_t
insn
,
const
DisasInsn
*
di
)
{
unsigned
rr
=
extract32
(
insn
,
16
,
5
);
TCGv_reg
tmp
,
reg
;
CHECK_MOST_PRIVILEGED
(
EXCP_PRIV_OPR
);
nullify_over
(
ctx
);
reg
=
load_gpr
(
ctx
,
rr
);
tmp
=
get_temp
(
ctx
);
gen_helper_swap_system_mask
(
tmp
,
cpu_env
,
reg
);
/* Exit the TB to recognize new interrupts. */
return
nullify_end
(
ctx
,
DISAS_IAQ_N_STALE_EXIT
);
}
#endif
/* !CONFIG_USER_ONLY */
static
const
DisasInsn
table_system
[]
=
{
{
0x00000000u
,
0xfc001fe0u
,
trans_break
},
/* We don't implement space register, so MTSP is a nop. */
...
...
@@ -1993,6 +2078,11 @@ static const DisasInsn table_system[] = {
{
0x000008a0u
,
0xfc1fffe0u
,
trans_mfctl
},
{
0x00000400u
,
0xffffffffu
,
trans_sync
},
{
0x000010a0u
,
0xfc1f3fe0u
,
trans_ldsid
},
#ifndef CONFIG_USER_ONLY
{
0x00000e60u
,
0xfc00ffe0u
,
trans_rsm
},
{
0x00000d60u
,
0xfc00ffe0u
,
trans_ssm
},
{
0x00001860u
,
0xffe0ffffu
,
trans_mtsm
},
#endif
};
static
DisasJumpType
trans_base_idx_mod
(
DisasContext
*
ctx
,
uint32_t
insn
,
...
...
@@ -4111,12 +4201,14 @@ static void hppa_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
static
void
hppa_tr_tb_stop
(
DisasContextBase
*
dcbase
,
CPUState
*
cs
)
{
DisasContext
*
ctx
=
container_of
(
dcbase
,
DisasContext
,
base
);
DisasJumpType
is_jmp
=
ctx
->
base
.
is_jmp
;
switch
(
ctx
->
base
.
is_jmp
)
{
switch
(
is_jmp
)
{
case
DISAS_NORETURN
:
break
;
case
DISAS_TOO_MANY
:
case
DISAS_IAQ_N_STALE
:
case
DISAS_IAQ_N_STALE_EXIT
:
copy_iaoq_entry
(
cpu_iaoq_f
,
ctx
->
iaoq_f
,
cpu_iaoq_f
);
copy_iaoq_entry
(
cpu_iaoq_b
,
ctx
->
iaoq_b
,
cpu_iaoq_b
);
nullify_save
(
ctx
);
...
...
@@ -4124,6 +4216,8 @@ static void hppa_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
case
DISAS_IAQ_N_UPDATED
:
if
(
ctx
->
base
.
singlestep_enabled
)
{
gen_excp_1
(
EXCP_DEBUG
);
}
else
if
(
is_jmp
==
DISAS_IAQ_N_STALE_EXIT
)
{
tcg_gen_exit_tb
(
0
);
}
else
{
tcg_gen_lookup_and_goto_ptr
();
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录