mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
armv5te support (Paul Brook)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1258 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
@@ -13,6 +13,8 @@ version 0.6.2:
|
||||
- initial APIC support
|
||||
- MMX/SSE/SSE2/PNI support
|
||||
- PC parallel port support (Mark Jonckheere)
|
||||
- initial SPARC64 support (Blue Swirl)
|
||||
- armv5te user mode support (Paul Brook)
|
||||
|
||||
version 0.6.1:
|
||||
|
||||
|
||||
+4
-3
@@ -160,7 +160,8 @@ int cpu_exec(CPUState *env1)
|
||||
env->CF = (psr >> 29) & 1;
|
||||
env->NZF = (psr & 0xc0000000) ^ 0x40000000;
|
||||
env->VF = (psr << 3) & 0x80000000;
|
||||
env->cpsr = psr & ~0xf0000000;
|
||||
env->QF = (psr >> 27) & 1;
|
||||
env->cpsr = psr & ~CACHED_CPSR_BITS;
|
||||
}
|
||||
#elif defined(TARGET_SPARC)
|
||||
#elif defined(TARGET_PPC)
|
||||
@@ -303,7 +304,7 @@ int cpu_exec(CPUState *env1)
|
||||
#elif defined(TARGET_ARM)
|
||||
env->cpsr = compute_cpsr();
|
||||
cpu_dump_state(env, logfile, fprintf, 0);
|
||||
env->cpsr &= ~0xf0000000;
|
||||
env->cpsr &= ~CACHED_CPSR_BITS;
|
||||
#elif defined(TARGET_SPARC)
|
||||
cpu_dump_state (env, logfile, fprintf, 0);
|
||||
#elif defined(TARGET_PPC)
|
||||
@@ -322,7 +323,7 @@ int cpu_exec(CPUState *env1)
|
||||
cs_base = env->segs[R_CS].base;
|
||||
pc = cs_base + env->eip;
|
||||
#elif defined(TARGET_ARM)
|
||||
flags = 0;
|
||||
flags = env->thumb;
|
||||
cs_base = 0;
|
||||
pc = env->regs[15];
|
||||
#elif defined(TARGET_SPARC)
|
||||
|
||||
@@ -30,7 +30,7 @@ struct target_pt_regs {
|
||||
#define ARM_NR_cacheflush (ARM_SYSCALL_BASE + 0xf0000 + 2)
|
||||
|
||||
#if defined(TARGET_WORDS_BIGENDIAN)
|
||||
#define UNAME_MACHINE "armv4b"
|
||||
#define UNAME_MACHINE "armv5teb"
|
||||
#else
|
||||
#define UNAME_MACHINE "armv4l"
|
||||
#define UNAME_MACHINE "armv5tel"
|
||||
#endif
|
||||
|
||||
+26
-2
@@ -2944,11 +2944,35 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
|
||||
#endif
|
||||
#ifdef TARGET_NR_getgroups32
|
||||
case TARGET_NR_getgroups32:
|
||||
goto unimplemented;
|
||||
{
|
||||
int gidsetsize = arg1;
|
||||
uint32_t *target_grouplist = (void *)arg2;
|
||||
gid_t *grouplist;
|
||||
int i;
|
||||
|
||||
grouplist = alloca(gidsetsize * sizeof(gid_t));
|
||||
ret = get_errno(getgroups(gidsetsize, grouplist));
|
||||
if (!is_error(ret)) {
|
||||
for(i = 0;i < gidsetsize; i++)
|
||||
put_user(grouplist[i], &target_grouplist[i]);
|
||||
}
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
#ifdef TARGET_NR_setgroups32
|
||||
case TARGET_NR_setgroups32:
|
||||
goto unimplemented;
|
||||
{
|
||||
int gidsetsize = arg1;
|
||||
uint32_t *target_grouplist = (void *)arg2;
|
||||
gid_t *grouplist;
|
||||
int i;
|
||||
|
||||
grouplist = alloca(gidsetsize * sizeof(gid_t));
|
||||
for(i = 0;i < gidsetsize; i++)
|
||||
get_user(grouplist[i], &target_grouplist[i]);
|
||||
ret = get_errno(setgroups(gidsetsize, grouplist));
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
#ifdef TARGET_NR_fchown32
|
||||
case TARGET_NR_fchown32:
|
||||
|
||||
@@ -35,6 +35,9 @@ typedef struct CPUARMState {
|
||||
uint32_t CF; /* 0 or 1 */
|
||||
uint32_t VF; /* V is the bit 31. All other bits are undefined */
|
||||
uint32_t NZF; /* N is bit 31. Z is computed from NZF */
|
||||
uint32_t QF; /* 0 or 1 */
|
||||
|
||||
int thumb; /* 0 = arm mode, 1 = thumb mode */
|
||||
|
||||
/* exception/interrupt handling */
|
||||
jmp_buf jmp_env;
|
||||
|
||||
+3
-1
@@ -31,12 +31,14 @@ void cpu_lock(void);
|
||||
void cpu_unlock(void);
|
||||
void cpu_loop_exit(void);
|
||||
|
||||
/* Implemented CPSR bits. */
|
||||
#define CACHED_CPSR_BITS 0xf8000000
|
||||
static inline int compute_cpsr(void)
|
||||
{
|
||||
int ZF;
|
||||
ZF = (env->NZF == 0);
|
||||
return env->cpsr | (env->NZF & 0x80000000) | (ZF << 30) |
|
||||
(env->CF << 29) | ((env->VF & 0x80000000) >> 3);
|
||||
(env->CF << 29) | ((env->VF & 0x80000000) >> 3) | (env->QF << 27);
|
||||
}
|
||||
|
||||
static inline void env_to_regs(void)
|
||||
|
||||
+144
@@ -81,8 +81,15 @@
|
||||
|
||||
#define REGNAME r15
|
||||
#define REG (env->regs[15])
|
||||
#define SET_REG(x) REG = x & ~(uint32_t)1
|
||||
#include "op_template.h"
|
||||
|
||||
void OPPROTO op_bx_T0(void)
|
||||
{
|
||||
env->regs[15] = T0 & ~(uint32_t)1;
|
||||
env->thumb = (T0 & 1) != 0;
|
||||
}
|
||||
|
||||
void OPPROTO op_movl_T0_0(void)
|
||||
{
|
||||
T0 = 0;
|
||||
@@ -382,6 +389,14 @@ void OPPROTO op_imull_T0_T1(void)
|
||||
T0 = res;
|
||||
}
|
||||
|
||||
/* 48 bit signed mul, top 32 bits */
|
||||
void OPPROTO op_imulw_T0_T1(void)
|
||||
{
|
||||
uint64_t res;
|
||||
res = (int64_t)((int32_t)T0) * (int64_t)((int32_t)T1);
|
||||
T0 = res >> 16;
|
||||
}
|
||||
|
||||
void OPPROTO op_addq_T0_T1(void)
|
||||
{
|
||||
uint64_t res;
|
||||
@@ -391,6 +406,15 @@ void OPPROTO op_addq_T0_T1(void)
|
||||
T0 = res;
|
||||
}
|
||||
|
||||
void OPPROTO op_addq_lo_T0_T1(void)
|
||||
{
|
||||
uint64_t res;
|
||||
res = ((uint64_t)T1 << 32) | T0;
|
||||
res += (uint64_t)(env->regs[PARAM1]);
|
||||
T1 = res >> 32;
|
||||
T0 = res;
|
||||
}
|
||||
|
||||
void OPPROTO op_logicq_cc(void)
|
||||
{
|
||||
env->NZF = (T1 & 0x80000000) | ((T0 | T1) != 0);
|
||||
@@ -694,6 +718,126 @@ void OPPROTO op_rorl_T1_T0_cc(void)
|
||||
FORCE_RET();
|
||||
}
|
||||
|
||||
/* misc */
|
||||
void OPPROTO op_clz_T0(void)
|
||||
{
|
||||
int count;
|
||||
for (count = 32; T0 > 0; count--)
|
||||
T0 = T0 >> 1;
|
||||
T0 = count;
|
||||
FORCE_RET();
|
||||
}
|
||||
|
||||
void OPPROTO op_sarl_T0_im(void)
|
||||
{
|
||||
T0 = (int32_t)T0 >> PARAM1;
|
||||
}
|
||||
|
||||
/* 16->32 Sign extend */
|
||||
void OPPROTO op_sxl_T0(void)
|
||||
{
|
||||
T0 = (int16_t)T0;
|
||||
}
|
||||
|
||||
void OPPROTO op_sxl_T1(void)
|
||||
{
|
||||
T1 = (int16_t)T1;
|
||||
}
|
||||
|
||||
#define SIGNBIT (uint32_t)0x80000000
|
||||
/* saturating arithmetic */
|
||||
void OPPROTO op_addl_T0_T1_setq(void)
|
||||
{
|
||||
uint32_t res;
|
||||
|
||||
res = T0 + T1;
|
||||
if (((res ^ T0) & SIGNBIT) && !((T0 ^ T1) & SIGNBIT))
|
||||
env->QF = 1;
|
||||
|
||||
T0 = res;
|
||||
FORCE_RET();
|
||||
}
|
||||
|
||||
void OPPROTO op_addl_T0_T1_saturate(void)
|
||||
{
|
||||
uint32_t res;
|
||||
|
||||
res = T0 + T1;
|
||||
if (((res ^ T0) & SIGNBIT) && !((T0 ^ T1) & SIGNBIT)) {
|
||||
env->QF = 1;
|
||||
if (T0 & SIGNBIT)
|
||||
T0 = 0x80000000;
|
||||
else
|
||||
T0 = 0x7fffffff;
|
||||
}
|
||||
else
|
||||
T0 = res;
|
||||
|
||||
FORCE_RET();
|
||||
}
|
||||
|
||||
void OPPROTO op_subl_T0_T1_saturate(void)
|
||||
{
|
||||
uint32_t res;
|
||||
|
||||
res = T0 - T1;
|
||||
if (((res ^ T0) & SIGNBIT) && ((T0 ^ T1) & SIGNBIT)) {
|
||||
env->QF = 1;
|
||||
if (T0 & SIGNBIT)
|
||||
T0 = 0x8000000;
|
||||
else
|
||||
T0 = 0x7fffffff;
|
||||
}
|
||||
else
|
||||
T0 = res;
|
||||
|
||||
FORCE_RET();
|
||||
}
|
||||
|
||||
/* thumb shift by immediate */
|
||||
void OPPROTO op_shll_T0_im_thumb(void)
|
||||
{
|
||||
int shift;
|
||||
shift = PARAM1;
|
||||
if (shift != 0) {
|
||||
env->CF = (T1 >> (32 - shift)) & 1;
|
||||
T0 = T0 << shift;
|
||||
}
|
||||
env->NZF = T0;
|
||||
FORCE_RET();
|
||||
}
|
||||
|
||||
void OPPROTO op_shrl_T0_im_thumb(void)
|
||||
{
|
||||
int shift;
|
||||
|
||||
shift = PARAM1;
|
||||
if (shift == 0) {
|
||||
env->CF = 0;
|
||||
T0 = 0;
|
||||
} else {
|
||||
env->CF = (T0 >> (shift - 1)) & 1;
|
||||
T0 = T0 >> shift;
|
||||
}
|
||||
FORCE_RET();
|
||||
}
|
||||
|
||||
void OPPROTO op_sarl_T0_im_thumb(void)
|
||||
{
|
||||
int shift;
|
||||
|
||||
shift = PARAM1;
|
||||
if (shift == 0) {
|
||||
T0 = ((int32_t)T0) >> 31;
|
||||
env->CF = T0 & 1;
|
||||
} else {
|
||||
env->CF = (T0 >> (shift - 1)) & 1;
|
||||
T0 = ((int32_t)T0) >> shift;
|
||||
}
|
||||
env->NZF = T0;
|
||||
FORCE_RET();
|
||||
}
|
||||
|
||||
/* exceptions */
|
||||
|
||||
void OPPROTO op_swi(void)
|
||||
|
||||
@@ -19,6 +19,10 @@
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef SET_REG
|
||||
#define SET_REG(x) REG = x
|
||||
#endif
|
||||
|
||||
void OPPROTO glue(op_movl_T0_, REGNAME)(void)
|
||||
{
|
||||
T0 = REG;
|
||||
@@ -36,13 +40,14 @@ void OPPROTO glue(op_movl_T2_, REGNAME)(void)
|
||||
|
||||
void OPPROTO glue(glue(op_movl_, REGNAME), _T0)(void)
|
||||
{
|
||||
REG = T0;
|
||||
SET_REG (T0);
|
||||
}
|
||||
|
||||
void OPPROTO glue(glue(op_movl_, REGNAME), _T1)(void)
|
||||
{
|
||||
REG = T1;
|
||||
SET_REG (T1);
|
||||
}
|
||||
|
||||
#undef REG
|
||||
#undef REGNAME
|
||||
#undef SET_REG
|
||||
|
||||
+718
-22
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user