Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
qemu
提交
d014c98c
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看板
提交
d014c98c
编写于
4月 29, 2003
作者:
B
bellard
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
sparc support
git-svn-id:
svn://svn.savannah.nongnu.org/qemu/trunk@119
c046a42c-6fe2-441c-8c8c-71466251a162
上级
a98fd896
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
310 addition
and
3 deletion
+310
-3
cpu-i386.h
cpu-i386.h
+6
-0
dyngen.c
dyngen.c
+191
-0
exec-i386.c
exec-i386.c
+14
-0
exec-i386.h
exec-i386.h
+5
-0
op-i386.c
op-i386.c
+79
-3
translate-i386.c
translate-i386.c
+15
-0
未找到文件。
cpu-i386.h
浏览文件 @
d014c98c
...
...
@@ -180,6 +180,12 @@ typedef struct CPUX86State {
/* emulator internal variables */
CPU86_LDouble
ft0
;
union
{
float
f
;
double
d
;
int
i32
;
int64_t
i64
;
}
fp_convert
;
/* segments */
uint32_t
segs
[
6
];
/* selector values */
...
...
dyngen.c
浏览文件 @
d014c98c
...
...
@@ -65,6 +65,20 @@
#define elf_check_arch(x) ((x) == EM_IA_64)
#define ELF_USES_RELOCA
#elif defined(HOST_SPARC)
#define ELF_CLASS ELFCLASS32
#define ELF_ARCH EM_SPARC
#define elf_check_arch(x) ((x) == EM_SPARC || (x) == EM_SPARC32PLUS)
#define ELF_USES_RELOCA
#elif defined(HOST_SPARC64)
#define ELF_CLASS ELFCLASS64
#define ELF_ARCH EM_SPARCV9
#define elf_check_arch(x) ((x) == EM_SPARCV9)
#define ELF_USES_RELOCA
#else
#error unsupported CPU - please update the code
#endif
...
...
@@ -326,6 +340,47 @@ void gen_code(const char *name, host_ulong offset, host_ulong size,
copy_size
=
p
-
p_start
;
}
break
;
case
EM_SPARC
:
case
EM_SPARC32PLUS
:
{
uint8_t
*
p
;
p
=
(
void
*
)(
p_end
-
8
);
if
(
p
<=
p_start
)
error
(
"empty code for %s"
,
name
);
if
(
get32
((
uint32_t
*
)(
p_start
+
0x0
))
!=
0x9de3bf98
)
error
(
"save %%sp,-104,%%sp expected at the start of %s "
"found [%08x]"
,
name
,
get32
((
uint32_t
*
)(
p_start
+
0x0
)));
if
(
get32
((
uint32_t
*
)(
p
+
0x0
))
!=
0x81c7e008
||
get32
((
uint32_t
*
)(
p
+
0x4
))
!=
0x81e80000
)
error
(
"ret; restore; expected at the end of %s found [%08x:%08x]"
,
name
,
get32
((
uint32_t
*
)(
p
+
0x0
)),
get32
((
uint32_t
*
)(
p
+
0x4
)));
copy_size
=
p
-
p_start
;
}
break
;
case
EM_SPARCV9
:
{
uint8_t
*
p
;
p
=
(
void
*
)(
p_end
-
8
);
if
(
p
<=
p_start
)
error
(
"empty code for %s"
,
name
);
if
(
get32
((
uint32_t
*
)(
p_start
+
0x0
))
!=
0x9de3bf40
)
error
(
"save %%sp,-192,%%sp expected at the start of %s "
"found [%08x]"
,
name
,
get32
((
uint32_t
*
)(
p_start
+
0x0
)));
if
(
get32
((
uint32_t
*
)(
p
+
0x0
))
!=
0x81cfe008
||
get32
((
uint32_t
*
)(
p
+
0x4
))
!=
0x01000000
)
error
(
"rett %%i7+8; nop; expected at the end of %s "
"found [%08x:%08x]"
,
name
,
get32
((
uint32_t
*
)(
p
+
0x0
)),
get32
((
uint32_t
*
)(
p
+
0x4
)));
copy_size
=
p
-
p_start
;
}
break
;
default:
error
(
"unknown ELF architecture"
);
}
...
...
@@ -375,6 +430,14 @@ void gen_code(const char *name, host_ulong offset, host_ulong size,
if
(
rel
->
r_offset
>=
offset
&&
rel
->
r_offset
<
offset
+
copy_size
)
{
sym_name
=
strtab
+
symtab
[
ELFW
(
R_SYM
)(
rel
->
r_info
)].
st_name
;
if
(
!
strstart
(
sym_name
,
"__op_param"
,
&
p
))
{
#if defined(HOST_SPARC)
if
(
sym_name
[
0
]
==
'.'
)
{
fprintf
(
outfile
,
"extern char __dot_%s __asm__(
\"
%s
\"
);
\n
"
,
sym_name
+
1
,
sym_name
);
continue
;
}
#endif
fprintf
(
outfile
,
"extern char %s;
\n
"
,
sym_name
);
}
}
...
...
@@ -554,6 +617,126 @@ void gen_code(const char *name, host_ulong offset, host_ulong size,
}
}
}
#elif defined(HOST_SPARC)
{
char
name
[
256
];
int
type
;
int
addend
;
for
(
i
=
0
,
rel
=
relocs
;
i
<
nb_relocs
;
i
++
,
rel
++
)
{
if
(
rel
->
r_offset
>=
offset
&&
rel
->
r_offset
<
offset
+
copy_size
)
{
sym_name
=
strtab
+
symtab
[
ELF32_R_SYM
(
rel
->
r_info
)].
st_name
;
if
(
strstart
(
sym_name
,
"__op_param"
,
&
p
))
{
snprintf
(
name
,
sizeof
(
name
),
"param%s"
,
p
);
}
else
{
if
(
sym_name
[
0
]
==
'.'
)
snprintf
(
name
,
sizeof
(
name
),
"(long)(&__dot_%s)"
,
sym_name
+
1
);
else
snprintf
(
name
,
sizeof
(
name
),
"(long)(&%s)"
,
sym_name
);
}
type
=
ELF32_R_TYPE
(
rel
->
r_info
);
addend
=
rel
->
r_addend
;
switch
(
type
)
{
case
R_SPARC_32
:
fprintf
(
outfile
,
" *(uint32_t *)(gen_code_ptr + %d) = %s + %d;
\n
"
,
rel
->
r_offset
-
offset
,
name
,
addend
);
break
;
case
R_SPARC_HI22
:
fprintf
(
outfile
,
" *(uint32_t *)(gen_code_ptr + %d) = "
"((*(uint32_t *)(gen_code_ptr + %d)) "
" & ~0x3fffff) "
" | ((%s + %d) & 0x3fffff);
\n
"
,
rel
->
r_offset
-
offset
,
rel
->
r_offset
-
offset
,
name
,
addend
);
break
;
case
R_SPARC_LO10
:
fprintf
(
outfile
,
" *(uint32_t *)(gen_code_ptr + %d) = "
"((*(uint32_t *)(gen_code_ptr + %d)) "
" & ~0x3ff) "
" | ((%s + %d) & 0x3ff);
\n
"
,
rel
->
r_offset
-
offset
,
rel
->
r_offset
-
offset
,
name
,
addend
);
break
;
case
R_SPARC_WDISP30
:
fprintf
(
outfile
,
" *(uint32_t *)(gen_code_ptr + %d) = "
"((*(uint32_t *)(gen_code_ptr + %d)) "
" & ~0x3fffffff) "
" | ((((%s + %d) - (long)gen_code_ptr)>>2) "
" & 0x3fffffff);
\n
"
,
rel
->
r_offset
-
offset
,
rel
->
r_offset
-
offset
,
name
,
addend
);
break
;
default:
error
(
"unsupported sparc relocation (%d)"
,
type
);
}
}
}
}
#elif defined(HOST_SPARC64)
{
char
name
[
256
];
int
type
;
int
addend
;
for
(
i
=
0
,
rel
=
relocs
;
i
<
nb_relocs
;
i
++
,
rel
++
)
{
if
(
rel
->
r_offset
>=
offset
&&
rel
->
r_offset
<
offset
+
copy_size
)
{
sym_name
=
strtab
+
symtab
[
ELF64_R_SYM
(
rel
->
r_info
)].
st_name
;
if
(
strstart
(
sym_name
,
"__op_param"
,
&
p
))
{
snprintf
(
name
,
sizeof
(
name
),
"param%s"
,
p
);
}
else
{
snprintf
(
name
,
sizeof
(
name
),
"(long)(&%s)"
,
sym_name
);
}
type
=
ELF64_R_TYPE
(
rel
->
r_info
);
addend
=
rel
->
r_addend
;
switch
(
type
)
{
case
R_SPARC_32
:
fprintf
(
outfile
,
" *(uint32_t *)(gen_code_ptr + %d) = %s + %d;
\n
"
,
rel
->
r_offset
-
offset
,
name
,
addend
);
break
;
case
R_SPARC_HI22
:
fprintf
(
outfile
,
" *(uint32_t *)(gen_code_ptr + %d) = "
"((*(uint32_t *)(gen_code_ptr + %d)) "
" & ~0x3fffff) "
" | ((%s + %d) & 0x3fffff);
\n
"
,
rel
->
r_offset
-
offset
,
rel
->
r_offset
-
offset
,
name
,
addend
);
break
;
case
R_SPARC_LO10
:
fprintf
(
outfile
,
" *(uint32_t *)(gen_code_ptr + %d) = "
"((*(uint32_t *)(gen_code_ptr + %d)) "
" & ~0x3ff) "
" | ((%s + %d) & 0x3ff);
\n
"
,
rel
->
r_offset
-
offset
,
rel
->
r_offset
-
offset
,
name
,
addend
);
break
;
case
R_SPARC_WDISP30
:
fprintf
(
outfile
,
" *(uint32_t *)(gen_code_ptr + %d) = "
"((*(uint32_t *)(gen_code_ptr + %d)) "
" & ~0x3fffffff) "
" | ((((%s + %d) - (long)gen_code_ptr)>>2) "
" & 0x3fffffff);
\n
"
,
rel
->
r_offset
-
offset
,
rel
->
r_offset
-
offset
,
name
,
addend
);
break
;
default:
error
(
"unsupported sparc64 relocation (%d)"
,
type
);
}
}
}
}
#else
#error unsupported CPU
#endif
...
...
@@ -759,6 +942,14 @@ fprintf(outfile,
case
EM_IA_64
:
fprintf
(
outfile
,
"*((uint32_t *)gen_code_ptr)++ = 0x00840008; /* br.ret.sptk.many b0;; */
\n
"
);
break
;
case
EM_SPARC
:
case
EM_SPARC32PLUS
:
case
EM_SPARCV9
:
/* Fill the delay slot. */
fprintf
(
outfile
,
"*((uint32_t *)gen_code_ptr) = *((uint32_t *)gen_code_ptr - 1); /* delay slot */
\n
"
);
fprintf
(
outfile
,
"*((uint32_t *)gen_code_ptr - 1) = 0x81c3e008; /* retl */
\n
"
);
fprintf
(
outfile
,
"gen_code_ptr++;
\n
"
);
break
;
default:
error
(
"unknown ELF architecture"
);
}
...
...
exec-i386.c
浏览文件 @
d014c98c
...
...
@@ -121,6 +121,20 @@ int testandset (int *p)
}
#endif
#ifdef __sparc__
static
inline
int
testandset
(
int
*
p
)
{
int
ret
;
__asm__
__volatile__
(
"ldstub [%1], %0"
:
"=r"
(
ret
)
:
"r"
(
p
)
:
"memory"
);
return
(
ret
?
1
:
0
);
}
#endif
int
global_cpu_lock
=
0
;
void
cpu_lock
(
void
)
...
...
exec-i386.h
浏览文件 @
d014c98c
...
...
@@ -93,6 +93,7 @@ register unsigned int T0 asm("l0");
register
unsigned
int
T1
asm
(
"l1"
);
register
unsigned
int
A0
asm
(
"l2"
);
register
struct
CPUX86State
*
env
asm
(
"l3"
);
#define USE_FP_CONVERT
#endif
#ifdef __s390__
register
unsigned
int
T0
asm
(
"r7"
);
...
...
@@ -160,6 +161,10 @@ register struct CPUX86State *env asm("r27");
#define ST(n) (env->fpregs[(env->fpstt + (n)) & 7])
#define ST1 ST(1)
#ifdef USE_FP_CONVERT
#define FP_CONVERT (env->fp_convert)
#endif
extern
int
__op_param1
,
__op_param2
,
__op_param3
;
#define PARAM1 ((long)(&__op_param1))
#define PARAM2 ((long)(&__op_param2))
...
...
op-i386.c
浏览文件 @
d014c98c
...
...
@@ -1605,12 +1605,22 @@ typedef union {
void
OPPROTO
op_flds_FT0_A0
(
void
)
{
#ifdef USE_FP_CONVERT
FP_CONVERT
.
i32
=
ldl
((
void
*
)
A0
);
FT0
=
FP_CONVERT
.
f
;
#else
FT0
=
ldfl
((
void
*
)
A0
);
#endif
}
void
OPPROTO
op_fldl_FT0_A0
(
void
)
{
#ifdef USE_FP_CONVERT
FP_CONVERT
.
i64
=
ldq
((
void
*
)
A0
);
FT0
=
FP_CONVERT
.
d
;
#else
FT0
=
ldfq
((
void
*
)
A0
);
#endif
}
/* helpers are needed to avoid static constant reference. XXX: find a better way */
...
...
@@ -1650,17 +1660,32 @@ void OPPROTO op_fildll_FT0_A0(void)
void
OPPROTO
op_fild_FT0_A0
(
void
)
{
#ifdef USE_FP_CONVERT
FP_CONVERT
.
i32
=
ldsw
((
void
*
)
A0
);
FT0
=
(
CPU86_LDouble
)
FP_CONVERT
.
i32
;
#else
FT0
=
(
CPU86_LDouble
)
ldsw
((
void
*
)
A0
);
#endif
}
void
OPPROTO
op_fildl_FT0_A0
(
void
)
{
#ifdef USE_FP_CONVERT
FP_CONVERT
.
i32
=
(
int32_t
)
ldl
((
void
*
)
A0
);
FT0
=
(
CPU86_LDouble
)
FP_CONVERT
.
i32
;
#else
FT0
=
(
CPU86_LDouble
)((
int32_t
)
ldl
((
void
*
)
A0
));
#endif
}
void
OPPROTO
op_fildll_FT0_A0
(
void
)
{
#ifdef USE_FP_CONVERT
FP_CONVERT
.
i64
=
(
int64_t
)
ldq
((
void
*
)
A0
);
FT0
=
(
CPU86_LDouble
)
FP_CONVERT
.
i64
;
#else
FT0
=
(
CPU86_LDouble
)((
int64_t
)
ldq
((
void
*
)
A0
));
#endif
}
#endif
...
...
@@ -1668,12 +1693,22 @@ void OPPROTO op_fildll_FT0_A0(void)
void
OPPROTO
op_flds_ST0_A0
(
void
)
{
#ifdef USE_FP_CONVERT
FP_CONVERT
.
i32
=
ldl
((
void
*
)
A0
);
ST0
=
FP_CONVERT
.
f
;
#else
ST0
=
ldfl
((
void
*
)
A0
);
#endif
}
void
OPPROTO
op_fldl_ST0_A0
(
void
)
{
#ifdef USE_FP_CONVERT
FP_CONVERT
.
i64
=
ldq
((
void
*
)
A0
);
ST0
=
FP_CONVERT
.
d
;
#else
ST0
=
ldfq
((
void
*
)
A0
);
#endif
}
#ifdef USE_X86LDOUBLE
...
...
@@ -1738,17 +1773,32 @@ void OPPROTO op_fildll_ST0_A0(void)
void
OPPROTO
op_fild_ST0_A0
(
void
)
{
#ifdef USE_FP_CONVERT
FP_CONVERT
.
i32
=
ldsw
((
void
*
)
A0
);
ST0
=
(
CPU86_LDouble
)
FP_CONVERT
.
i32
;
#else
ST0
=
(
CPU86_LDouble
)
ldsw
((
void
*
)
A0
);
#endif
}
void
OPPROTO
op_fildl_ST0_A0
(
void
)
{
#ifdef USE_FP_CONVERT
FP_CONVERT
.
i32
=
(
int32_t
)
ldl
((
void
*
)
A0
);
ST0
=
(
CPU86_LDouble
)
FP_CONVERT
.
i32
;
#else
ST0
=
(
CPU86_LDouble
)((
int32_t
)
ldl
((
void
*
)
A0
));
#endif
}
void
OPPROTO
op_fildll_ST0_A0
(
void
)
{
#ifdef USE_FP_CONVERT
FP_CONVERT
.
i64
=
(
int64_t
)
ldq
((
void
*
)
A0
);
ST0
=
(
CPU86_LDouble
)
FP_CONVERT
.
i64
;
#else
ST0
=
(
CPU86_LDouble
)((
int64_t
)
ldq
((
void
*
)
A0
));
#endif
}
#endif
...
...
@@ -1757,7 +1807,12 @@ void OPPROTO op_fildll_ST0_A0(void)
void
OPPROTO
op_fsts_ST0_A0
(
void
)
{
#ifdef USE_FP_CONVERT
FP_CONVERT
.
d
=
ST0
;
stfl
((
void
*
)
A0
,
FP_CONVERT
.
f
);
#else
stfl
((
void
*
)
A0
,
(
float
)
ST0
);
#endif
}
void
OPPROTO
op_fstl_ST0_A0
(
void
)
...
...
@@ -1792,22 +1847,43 @@ void OPPROTO op_fstt_ST0_A0(void)
void
OPPROTO
op_fist_ST0_A0
(
void
)
{
#if defined(__sparc__) && !defined(__sparc_v9__)
register
CPU86_LDouble
d
asm
(
"o0"
);
#else
CPU86_LDouble
d
;
#endif
int
val
;
val
=
lrint
(
ST0
);
d
=
ST0
;
val
=
lrint
(
d
);
stw
((
void
*
)
A0
,
val
);
}
void
OPPROTO
op_fistl_ST0_A0
(
void
)
{
#if defined(__sparc__) && !defined(__sparc_v9__)
register
CPU86_LDouble
d
asm
(
"o0"
);
#else
CPU86_LDouble
d
;
#endif
int
val
;
val
=
lrint
(
ST0
);
d
=
ST0
;
val
=
lrint
(
d
);
stl
((
void
*
)
A0
,
val
);
}
void
OPPROTO
op_fistll_ST0_A0
(
void
)
{
#if defined(__sparc__) && !defined(__sparc_v9__)
register
CPU86_LDouble
d
asm
(
"o0"
);
#else
CPU86_LDouble
d
;
#endif
int64_t
val
;
val
=
llrint
(
ST0
);
d
=
ST0
;
val
=
llrint
(
d
);
stq
((
void
*
)
A0
,
val
);
}
...
...
translate-i386.c
浏览文件 @
d014c98c
...
...
@@ -89,6 +89,21 @@ static inline void flush_icache_range(unsigned long start, unsigned long stop)
}
#endif
#ifdef __sparc__
static
void
inline
flush_icache_range
(
unsigned
long
start
,
unsigned
long
stop
)
{
unsigned
long
p
;
p
=
start
&
~
(
8UL
-
1UL
);
stop
=
(
stop
+
(
8UL
-
1UL
))
&
~
(
8UL
-
1UL
);
for
(;
p
<
stop
;
p
+=
8
)
__asm__
__volatile__
(
"flush
\t
%0"
:
:
"r"
(
p
));
}
#endif
extern
FILE
*
logfile
;
extern
int
loglevel
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录