mirror of
https://github.com/qemu/qemu.git
synced 2024-11-28 14:24:02 +08:00
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:
parent
2a39bc41cb
commit
b26eefb68e
@ -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 *);
|
||||
|
@ -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
6
target-arm/helpers.h
Normal 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))
|
330
target-arm/op.c
330
target-arm/op.c
@ -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)
|
||||
|
@ -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
Loading…
Reference in New Issue
Block a user