ARM TCG conversion 1/16.

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4138 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
pbrook 2008-03-31 03:44:26 +00:00
parent 2a39bc41cb
commit b26eefb68e
6 changed files with 434 additions and 673 deletions

View File

@ -89,7 +89,7 @@ typedef struct CPUARMState {
uint32_t NZF; /* N is bit 31. Z is computed from NZF */
uint32_t QF; /* 0 or 1 */
uint32_t GE; /* cpsr[19:16] */
int thumb; /* cprs[5]. 0 = arm mode, 1 = thumb mode. */
uint32_t thumb; /* cpsr[5]. 0 = arm mode, 1 = thumb mode. */
uint32_t condexec_bits; /* IT bits. cpsr[15:10,26:25]. */
/* System control coprocessor (cp15) */
@ -207,6 +207,7 @@ typedef struct CPUARMState {
} CPUARMState;
CPUARMState *cpu_arm_init(const char *cpu_model);
void arm_translate_init(void);
int cpu_arm_exec(CPUARMState *s);
void cpu_arm_close(CPUARMState *s);
void do_interrupt(CPUARMState *);

View File

@ -5,6 +5,7 @@
#include "cpu.h"
#include "exec-all.h"
#include "gdbstub.h"
#include "helpers.h"
static uint32_t cortexa8_cp15_c0_c1[8] =
{ 0x1031, 0x11, 0x400, 0, 0x31100003, 0x20000000, 0x01202000, 0x11 };
@ -174,6 +175,7 @@ CPUARMState *cpu_arm_init(const char *cpu_model)
{
CPUARMState *env;
uint32_t id;
static int inited = 0;
id = cpu_arm_find_by_name(cpu_model);
if (id == 0)
@ -182,6 +184,11 @@ CPUARMState *cpu_arm_init(const char *cpu_model)
if (!env)
return NULL;
cpu_exec_init(env);
if (!inited) {
inited = 1;
arm_translate_init();
}
env->cpu_model_str = cpu_model;
env->cp15.c0_cpuid = id;
cpu_reset(env);
@ -315,6 +322,24 @@ void cpsr_write(CPUARMState *env, uint32_t val, uint32_t mask)
env->uncached_cpsr = (env->uncached_cpsr & ~mask) | (val & mask);
}
#define HELPER(x) helper_##x
/* Sign/zero extend */
uint32_t HELPER(sxtb16)(uint32_t x)
{
uint32_t res;
res = (uint16_t)(int8_t)x;
res |= (uint32_t)(int8_t)(x >> 16) << 16;
return res;
}
uint32_t HELPER(uxtb16)(uint32_t x)
{
uint32_t res;
res = (uint16_t)(uint8_t)x;
res |= (uint32_t)(uint8_t)(x >> 16) << 16;
return res;
}
#if defined(CONFIG_USER_ONLY)
void do_interrupt (CPUState *env)
@ -1861,3 +1886,4 @@ void cpu_arm_set_cp_io(CPUARMState *env, int cpnum,
}
#endif

6
target-arm/helpers.h Normal file
View File

@ -0,0 +1,6 @@
#ifndef DEF_HELPER
#define DEF_HELPER(name, ret, args) ret helper_##name args;
#endif
DEF_HELPER(sxtb16, uint32_t, (uint32_t))
DEF_HELPER(uxtb16, uint32_t, (uint32_t))

View File

@ -20,122 +20,6 @@
*/
#include "exec.h"
#define REGNAME r0
#define REG (env->regs[0])
#include "op_template.h"
#define REGNAME r1
#define REG (env->regs[1])
#include "op_template.h"
#define REGNAME r2
#define REG (env->regs[2])
#include "op_template.h"
#define REGNAME r3
#define REG (env->regs[3])
#include "op_template.h"
#define REGNAME r4
#define REG (env->regs[4])
#include "op_template.h"
#define REGNAME r5
#define REG (env->regs[5])
#include "op_template.h"
#define REGNAME r6
#define REG (env->regs[6])
#include "op_template.h"
#define REGNAME r7
#define REG (env->regs[7])
#include "op_template.h"
#define REGNAME r8
#define REG (env->regs[8])
#include "op_template.h"
#define REGNAME r9
#define REG (env->regs[9])
#include "op_template.h"
#define REGNAME r10
#define REG (env->regs[10])
#include "op_template.h"
#define REGNAME r11
#define REG (env->regs[11])
#include "op_template.h"
#define REGNAME r12
#define REG (env->regs[12])
#include "op_template.h"
#define REGNAME r13
#define REG (env->regs[13])
#include "op_template.h"
#define REGNAME r14
#define REG (env->regs[14])
#include "op_template.h"
#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;
}
void OPPROTO op_movl_T0_im(void)
{
T0 = PARAM1;
}
void OPPROTO op_movl_T1_im(void)
{
T1 = PARAM1;
}
void OPPROTO op_mov_CF_T1(void)
{
env->CF = ((uint32_t)T1) >> 31;
}
void OPPROTO op_movl_T2_im(void)
{
T2 = PARAM1;
}
void OPPROTO op_addl_T1_im(void)
{
T1 += PARAM1;
}
void OPPROTO op_addl_T1_T2(void)
{
T1 += T2;
}
void OPPROTO op_subl_T1_T2(void)
{
T1 -= T2;
}
void OPPROTO op_addl_T0_T1(void)
{
T0 += T1;
}
void OPPROTO op_addl_T0_T1_cc(void)
{
unsigned int src1;
@ -146,11 +30,6 @@ void OPPROTO op_addl_T0_T1_cc(void)
env->VF = (src1 ^ T1 ^ -1) & (src1 ^ T0);
}
void OPPROTO op_adcl_T0_T1(void)
{
T0 += T1 + env->CF;
}
void OPPROTO op_adcl_T0_T1_cc(void)
{
unsigned int src1;
@ -169,11 +48,6 @@ void OPPROTO op_adcl_T0_T1_cc(void)
#define OPSUB(sub, sbc, res, T0, T1) \
\
void OPPROTO op_ ## sub ## l_T0_T1(void) \
{ \
res = T0 - T1; \
} \
\
void OPPROTO op_ ## sub ## l_T0_T1_cc(void) \
{ \
unsigned int src1; \
@ -211,46 +85,6 @@ OPSUB(sub, sbc, T0, T0, T1)
OPSUB(rsb, rsc, T0, T1, T0)
void OPPROTO op_andl_T0_T1(void)
{
T0 &= T1;
}
void OPPROTO op_xorl_T0_T1(void)
{
T0 ^= T1;
}
void OPPROTO op_orl_T0_T1(void)
{
T0 |= T1;
}
void OPPROTO op_bicl_T0_T1(void)
{
T0 &= ~T1;
}
void OPPROTO op_notl_T0(void)
{
T0 = ~T0;
}
void OPPROTO op_notl_T1(void)
{
T1 = ~T1;
}
void OPPROTO op_logic_T0_cc(void)
{
env->NZF = T0;
}
void OPPROTO op_logic_T1_cc(void)
{
env->NZF = T1;
}
#define EIP (env->regs[15])
void OPPROTO op_test_eq(void)
@ -485,51 +319,6 @@ void OPPROTO op_clrex(void)
/* shifts */
/* Used by NEON. */
void OPPROTO op_shll_T0_im(void)
{
T1 = T1 << PARAM1;
}
/* T1 based */
void OPPROTO op_shll_T1_im(void)
{
T1 = T1 << PARAM1;
}
void OPPROTO op_shrl_T1_im(void)
{
T1 = (uint32_t)T1 >> PARAM1;
}
void OPPROTO op_shrl_T1_0(void)
{
T1 = 0;
}
void OPPROTO op_sarl_T1_im(void)
{
T1 = (int32_t)T1 >> PARAM1;
}
void OPPROTO op_sarl_T1_0(void)
{
T1 = (int32_t)T1 >> 31;
}
void OPPROTO op_rorl_T1_im(void)
{
int shift;
shift = PARAM1;
T1 = ((uint32_t)T1 >> shift) | (T1 << (32 - shift));
}
void OPPROTO op_rrxl_T1(void)
{
T1 = ((uint32_t)T1 >> 1) | ((uint32_t)env->CF << 31);
}
/* T1 based, set C flag */
void OPPROTO op_shll_T1_im_cc(void)
{
@ -577,44 +366,6 @@ void OPPROTO op_rrxl_T1_cc(void)
env->CF = c;
}
/* T2 based */
void OPPROTO op_shll_T2_im(void)
{
T2 = T2 << PARAM1;
}
void OPPROTO op_shrl_T2_im(void)
{
T2 = (uint32_t)T2 >> PARAM1;
}
void OPPROTO op_shrl_T2_0(void)
{
T2 = 0;
}
void OPPROTO op_sarl_T2_im(void)
{
T2 = (int32_t)T2 >> PARAM1;
}
void OPPROTO op_sarl_T2_0(void)
{
T2 = (int32_t)T2 >> 31;
}
void OPPROTO op_rorl_T2_im(void)
{
int shift;
shift = PARAM1;
T2 = ((uint32_t)T2 >> shift) | (T2 << (32 - shift));
}
void OPPROTO op_rrxl_T2(void)
{
T2 = ((uint32_t)T2 >> 1) | ((uint32_t)env->CF << 31);
}
/* T1 based, use T0 as shift count */
void OPPROTO op_shll_T1_T0(void)
@ -733,53 +484,6 @@ void OPPROTO op_clz_T0(void)
FORCE_RET();
}
void OPPROTO op_sarl_T0_im(void)
{
T0 = (int32_t)T0 >> PARAM1;
}
/* Sign/zero extend */
void OPPROTO op_sxth_T0(void)
{
T0 = (int16_t)T0;
}
void OPPROTO op_sxth_T1(void)
{
T1 = (int16_t)T1;
}
void OPPROTO op_sxtb_T1(void)
{
T1 = (int8_t)T1;
}
void OPPROTO op_uxtb_T1(void)
{
T1 = (uint8_t)T1;
}
void OPPROTO op_uxth_T1(void)
{
T1 = (uint16_t)T1;
}
void OPPROTO op_sxtb16_T1(void)
{
uint32_t res;
res = (uint16_t)(int8_t)T1;
res |= (uint32_t)(int8_t)(T1 >> 16) << 16;
T1 = res;
}
void OPPROTO op_uxtb16_T1(void)
{
uint32_t res;
res = (uint16_t)(uint8_t)T1;
res |= (uint32_t)(uint8_t)(T1 >> 16) << 16;
T1 = res;
}
#define SIGNBIT (uint32_t)0x80000000
/* saturating arithmetic */
void OPPROTO op_addl_T0_T1_setq(void)
@ -1369,31 +1073,6 @@ void OPPROTO op_movl_user_T0(void)
FORCE_RET();
}
void OPPROTO op_movl_T0_T1(void)
{
T0 = T1;
}
void OPPROTO op_movl_T0_T2(void)
{
T0 = T2;
}
void OPPROTO op_movl_T1_T0(void)
{
T1 = T0;
}
void OPPROTO op_movl_T1_T2(void)
{
T1 = T2;
}
void OPPROTO op_movl_T2_T0(void)
{
T2 = T0;
}
/* ARMv6 Media instructions. */
/* Note that signed overflow is undefined in C. The following routines are
@ -1769,15 +1448,6 @@ void OPPROTO op_usat16_T1(void)
}
/* Dual 16-bit add. */
void OPPROTO op_add16_T1_T2(void)
{
uint32_t mask;
mask = (T0 & T1) & 0x8000;
T0 ^= ~0x8000;
T1 ^= ~0x8000;
T0 = (T0 + T1) ^ mask;
}
static inline uint8_t do_usad(uint8_t a, uint8_t b)
{
if (a > b)

View File

@ -1,53 +0,0 @@
/*
* ARM micro operations (templates for various register related
* operations)
*
* Copyright (c) 2003 Fabrice Bellard
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* 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;
}
void OPPROTO glue(op_movl_T1_, REGNAME)(void)
{
T1 = REG;
}
void OPPROTO glue(op_movl_T2_, REGNAME)(void)
{
T2 = REG;
}
void OPPROTO glue(glue(op_movl_, REGNAME), _T0)(void)
{
SET_REG (T0);
}
void OPPROTO glue(glue(op_movl_, REGNAME), _T1)(void)
{
SET_REG (T1);
}
#undef REG
#undef REGNAME
#undef SET_REG

File diff suppressed because it is too large Load Diff