ARM TCG conversion 10/16.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4147 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
		
							parent
							
								
									b010980544
								
							
						
					
					
						commit
						4373f3ceeb
					
				@ -168,9 +168,6 @@ typedef struct CPUARMState {
 | 
				
			|||||||
        int vec_len;
 | 
					        int vec_len;
 | 
				
			||||||
        int vec_stride;
 | 
					        int vec_stride;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /* Temporary variables if we don't have spare fp regs.  */
 | 
					 | 
				
			||||||
        float32 tmp0s, tmp1s;
 | 
					 | 
				
			||||||
        float64 tmp0d, tmp1d;
 | 
					 | 
				
			||||||
        /* scratch space when Tn are not sufficient.  */
 | 
					        /* scratch space when Tn are not sufficient.  */
 | 
				
			||||||
        uint32_t scratch[8];
 | 
					        uint32_t scratch[8];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -25,13 +25,6 @@ register uint32_t T0 asm(AREG1);
 | 
				
			|||||||
register uint32_t T1 asm(AREG2);
 | 
					register uint32_t T1 asm(AREG2);
 | 
				
			||||||
register uint32_t T2 asm(AREG3);
 | 
					register uint32_t T2 asm(AREG3);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* TODO: Put these in FP regs on targets that have such things.  */
 | 
					 | 
				
			||||||
/* It is ok for FT0s and FT0d to overlap.  Likewise FT1s and FT1d.  */
 | 
					 | 
				
			||||||
#define FT0s env->vfp.tmp0s
 | 
					 | 
				
			||||||
#define FT1s env->vfp.tmp1s
 | 
					 | 
				
			||||||
#define FT0d env->vfp.tmp0d
 | 
					 | 
				
			||||||
#define FT1d env->vfp.tmp1d
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define M0   env->iwmmxt.val
 | 
					#define M0   env->iwmmxt.val
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "cpu.h"
 | 
					#include "cpu.h"
 | 
				
			||||||
@ -83,23 +76,5 @@ void cpu_loop_exit(void);
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
void raise_exception(int);
 | 
					void raise_exception(int);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void do_vfp_abss(void);
 | 
					 | 
				
			||||||
void do_vfp_absd(void);
 | 
					 | 
				
			||||||
void do_vfp_negs(void);
 | 
					 | 
				
			||||||
void do_vfp_negd(void);
 | 
					 | 
				
			||||||
void do_vfp_sqrts(void);
 | 
					 | 
				
			||||||
void do_vfp_sqrtd(void);
 | 
					 | 
				
			||||||
void do_vfp_cmps(void);
 | 
					 | 
				
			||||||
void do_vfp_cmpd(void);
 | 
					 | 
				
			||||||
void do_vfp_cmpes(void);
 | 
					 | 
				
			||||||
void do_vfp_cmped(void);
 | 
					 | 
				
			||||||
void do_vfp_set_fpscr(void);
 | 
					 | 
				
			||||||
void do_vfp_get_fpscr(void);
 | 
					 | 
				
			||||||
float32 helper_recps_f32(float32, float32);
 | 
					 | 
				
			||||||
float32 helper_rsqrts_f32(float32, float32);
 | 
					 | 
				
			||||||
uint32_t helper_recpe_u32(uint32_t);
 | 
					 | 
				
			||||||
uint32_t helper_rsqrte_u32(uint32_t);
 | 
					 | 
				
			||||||
float32 helper_recpe_f32(float32);
 | 
					 | 
				
			||||||
float32 helper_rsqrte_f32(float32);
 | 
					 | 
				
			||||||
void helper_neon_tbl(int rn, int maxindex);
 | 
					void helper_neon_tbl(int rn, int maxindex);
 | 
				
			||||||
uint32_t helper_neon_mul_p8(uint32_t op1, uint32_t op2);
 | 
					uint32_t helper_neon_mul_p8(uint32_t op1, uint32_t op2);
 | 
				
			||||||
 | 
				
			|||||||
@ -2167,3 +2167,366 @@ uint32_t HELPER(sel_flags)(uint32_t flags, uint32_t a, uint32_t b)
 | 
				
			|||||||
    return (a & mask) | (b & ~mask);
 | 
					    return (a & mask) | (b & ~mask);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* VFP support.  We follow the convention used for VFP instrunctions:
 | 
				
			||||||
 | 
					   Single precition routines have a "s" suffix, double precision a
 | 
				
			||||||
 | 
					   "d" suffix.  */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Convert host exception flags to vfp form.  */
 | 
				
			||||||
 | 
					static inline int vfp_exceptbits_from_host(int host_bits)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int target_bits = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (host_bits & float_flag_invalid)
 | 
				
			||||||
 | 
					        target_bits |= 1;
 | 
				
			||||||
 | 
					    if (host_bits & float_flag_divbyzero)
 | 
				
			||||||
 | 
					        target_bits |= 2;
 | 
				
			||||||
 | 
					    if (host_bits & float_flag_overflow)
 | 
				
			||||||
 | 
					        target_bits |= 4;
 | 
				
			||||||
 | 
					    if (host_bits & float_flag_underflow)
 | 
				
			||||||
 | 
					        target_bits |= 8;
 | 
				
			||||||
 | 
					    if (host_bits & float_flag_inexact)
 | 
				
			||||||
 | 
					        target_bits |= 0x10;
 | 
				
			||||||
 | 
					    return target_bits;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint32_t HELPER(vfp_get_fpscr)(CPUState *env)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int i;
 | 
				
			||||||
 | 
					    uint32_t fpscr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fpscr = (env->vfp.xregs[ARM_VFP_FPSCR] & 0xffc8ffff)
 | 
				
			||||||
 | 
					            | (env->vfp.vec_len << 16)
 | 
				
			||||||
 | 
					            | (env->vfp.vec_stride << 20);
 | 
				
			||||||
 | 
					    i = get_float_exception_flags(&env->vfp.fp_status);
 | 
				
			||||||
 | 
					    fpscr |= vfp_exceptbits_from_host(i);
 | 
				
			||||||
 | 
					    return fpscr;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Convert vfp exception flags to target form.  */
 | 
				
			||||||
 | 
					static inline int vfp_exceptbits_to_host(int target_bits)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int host_bits = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (target_bits & 1)
 | 
				
			||||||
 | 
					        host_bits |= float_flag_invalid;
 | 
				
			||||||
 | 
					    if (target_bits & 2)
 | 
				
			||||||
 | 
					        host_bits |= float_flag_divbyzero;
 | 
				
			||||||
 | 
					    if (target_bits & 4)
 | 
				
			||||||
 | 
					        host_bits |= float_flag_overflow;
 | 
				
			||||||
 | 
					    if (target_bits & 8)
 | 
				
			||||||
 | 
					        host_bits |= float_flag_underflow;
 | 
				
			||||||
 | 
					    if (target_bits & 0x10)
 | 
				
			||||||
 | 
					        host_bits |= float_flag_inexact;
 | 
				
			||||||
 | 
					    return host_bits;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void HELPER(vfp_set_fpscr)(CPUState *env, uint32_t val)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int i;
 | 
				
			||||||
 | 
					    uint32_t changed;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    changed = env->vfp.xregs[ARM_VFP_FPSCR];
 | 
				
			||||||
 | 
					    env->vfp.xregs[ARM_VFP_FPSCR] = (val & 0xffc8ffff);
 | 
				
			||||||
 | 
					    env->vfp.vec_len = (val >> 16) & 7;
 | 
				
			||||||
 | 
					    env->vfp.vec_stride = (val >> 20) & 3;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    changed ^= val;
 | 
				
			||||||
 | 
					    if (changed & (3 << 22)) {
 | 
				
			||||||
 | 
					        i = (val >> 22) & 3;
 | 
				
			||||||
 | 
					        switch (i) {
 | 
				
			||||||
 | 
					        case 0:
 | 
				
			||||||
 | 
					            i = float_round_nearest_even;
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        case 1:
 | 
				
			||||||
 | 
					            i = float_round_up;
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        case 2:
 | 
				
			||||||
 | 
					            i = float_round_down;
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        case 3:
 | 
				
			||||||
 | 
					            i = float_round_to_zero;
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        set_float_rounding_mode(i, &env->vfp.fp_status);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    i = vfp_exceptbits_to_host((val >> 8) & 0x1f);
 | 
				
			||||||
 | 
					    set_float_exception_flags(i, &env->vfp.fp_status);
 | 
				
			||||||
 | 
					    /* XXX: FZ and DN are not implemented.  */
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define VFP_HELPER(name, p) HELPER(glue(glue(vfp_,name),p))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define VFP_BINOP(name) \
 | 
				
			||||||
 | 
					float32 VFP_HELPER(name, s)(float32 a, float32 b, CPUState *env) \
 | 
				
			||||||
 | 
					{ \
 | 
				
			||||||
 | 
					    return float32_ ## name (a, b, &env->vfp.fp_status); \
 | 
				
			||||||
 | 
					} \
 | 
				
			||||||
 | 
					float64 VFP_HELPER(name, d)(float64 a, float64 b, CPUState *env) \
 | 
				
			||||||
 | 
					{ \
 | 
				
			||||||
 | 
					    return float64_ ## name (a, b, &env->vfp.fp_status); \
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					VFP_BINOP(add)
 | 
				
			||||||
 | 
					VFP_BINOP(sub)
 | 
				
			||||||
 | 
					VFP_BINOP(mul)
 | 
				
			||||||
 | 
					VFP_BINOP(div)
 | 
				
			||||||
 | 
					#undef VFP_BINOP
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					float32 VFP_HELPER(neg, s)(float32 a)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return float32_chs(a);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					float64 VFP_HELPER(neg, d)(float64 a)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return float32_chs(a);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					float32 VFP_HELPER(abs, s)(float32 a)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return float32_abs(a);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					float64 VFP_HELPER(abs, d)(float64 a)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return float32_abs(a);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					float32 VFP_HELPER(sqrt, s)(float32 a, CPUState *env)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return float32_sqrt(a, &env->vfp.fp_status);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					float64 VFP_HELPER(sqrt, d)(float64 a, CPUState *env)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return float64_sqrt(a, &env->vfp.fp_status);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* XXX: check quiet/signaling case */
 | 
				
			||||||
 | 
					#define DO_VFP_cmp(p, type) \
 | 
				
			||||||
 | 
					void VFP_HELPER(cmp, p)(type a, type b, CPUState *env)  \
 | 
				
			||||||
 | 
					{ \
 | 
				
			||||||
 | 
					    uint32_t flags; \
 | 
				
			||||||
 | 
					    switch(type ## _compare_quiet(a, b, &env->vfp.fp_status)) { \
 | 
				
			||||||
 | 
					    case 0: flags = 0x6; break; \
 | 
				
			||||||
 | 
					    case -1: flags = 0x8; break; \
 | 
				
			||||||
 | 
					    case 1: flags = 0x2; break; \
 | 
				
			||||||
 | 
					    default: case 2: flags = 0x3; break; \
 | 
				
			||||||
 | 
					    } \
 | 
				
			||||||
 | 
					    env->vfp.xregs[ARM_VFP_FPSCR] = (flags << 28) \
 | 
				
			||||||
 | 
					        | (env->vfp.xregs[ARM_VFP_FPSCR] & 0x0fffffff); \
 | 
				
			||||||
 | 
					} \
 | 
				
			||||||
 | 
					void VFP_HELPER(cmpe, p)(type a, type b, CPUState *env) \
 | 
				
			||||||
 | 
					{ \
 | 
				
			||||||
 | 
					    uint32_t flags; \
 | 
				
			||||||
 | 
					    switch(type ## _compare(a, b, &env->vfp.fp_status)) { \
 | 
				
			||||||
 | 
					    case 0: flags = 0x6; break; \
 | 
				
			||||||
 | 
					    case -1: flags = 0x8; break; \
 | 
				
			||||||
 | 
					    case 1: flags = 0x2; break; \
 | 
				
			||||||
 | 
					    default: case 2: flags = 0x3; break; \
 | 
				
			||||||
 | 
					    } \
 | 
				
			||||||
 | 
					    env->vfp.xregs[ARM_VFP_FPSCR] = (flags << 28) \
 | 
				
			||||||
 | 
					        | (env->vfp.xregs[ARM_VFP_FPSCR] & 0x0fffffff); \
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					DO_VFP_cmp(s, float32)
 | 
				
			||||||
 | 
					DO_VFP_cmp(d, float64)
 | 
				
			||||||
 | 
					#undef DO_VFP_cmp
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Helper routines to perform bitwise copies between float and int.  */
 | 
				
			||||||
 | 
					static inline float32 vfp_itos(uint32_t i)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    union {
 | 
				
			||||||
 | 
					        uint32_t i;
 | 
				
			||||||
 | 
					        float32 s;
 | 
				
			||||||
 | 
					    } v;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    v.i = i;
 | 
				
			||||||
 | 
					    return v.s;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline uint32_t vfp_stoi(float32 s)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    union {
 | 
				
			||||||
 | 
					        uint32_t i;
 | 
				
			||||||
 | 
					        float32 s;
 | 
				
			||||||
 | 
					    } v;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    v.s = s;
 | 
				
			||||||
 | 
					    return v.i;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline float64 vfp_itod(uint64_t i)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    union {
 | 
				
			||||||
 | 
					        uint64_t i;
 | 
				
			||||||
 | 
					        float64 d;
 | 
				
			||||||
 | 
					    } v;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    v.i = i;
 | 
				
			||||||
 | 
					    return v.d;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline uint64_t vfp_dtoi(float64 d)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    union {
 | 
				
			||||||
 | 
					        uint64_t i;
 | 
				
			||||||
 | 
					        float64 d;
 | 
				
			||||||
 | 
					    } v;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    v.d = d;
 | 
				
			||||||
 | 
					    return v.i;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Integer to float conversion.  */
 | 
				
			||||||
 | 
					float32 VFP_HELPER(uito, s)(float32 x, CPUState *env)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return uint32_to_float32(vfp_stoi(x), &env->vfp.fp_status);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					float64 VFP_HELPER(uito, d)(float32 x, CPUState *env)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return uint32_to_float64(vfp_stoi(x), &env->vfp.fp_status);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					float32 VFP_HELPER(sito, s)(float32 x, CPUState *env)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return int32_to_float32(vfp_stoi(x), &env->vfp.fp_status);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					float64 VFP_HELPER(sito, d)(float32 x, CPUState *env)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return int32_to_float64(vfp_stoi(x), &env->vfp.fp_status);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Float to integer conversion.  */
 | 
				
			||||||
 | 
					float32 VFP_HELPER(toui, s)(float32 x, CPUState *env)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return vfp_itos(float32_to_uint32(x, &env->vfp.fp_status));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					float32 VFP_HELPER(toui, d)(float64 x, CPUState *env)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return vfp_itos(float64_to_uint32(x, &env->vfp.fp_status));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					float32 VFP_HELPER(tosi, s)(float32 x, CPUState *env)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return vfp_itos(float32_to_int32(x, &env->vfp.fp_status));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					float32 VFP_HELPER(tosi, d)(float64 x, CPUState *env)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return vfp_itos(float64_to_int32(x, &env->vfp.fp_status));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					float32 VFP_HELPER(touiz, s)(float32 x, CPUState *env)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return vfp_itos(float32_to_uint32_round_to_zero(x, &env->vfp.fp_status));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					float32 VFP_HELPER(touiz, d)(float64 x, CPUState *env)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return vfp_itos(float64_to_uint32_round_to_zero(x, &env->vfp.fp_status));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					float32 VFP_HELPER(tosiz, s)(float32 x, CPUState *env)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return vfp_itos(float32_to_int32_round_to_zero(x, &env->vfp.fp_status));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					float32 VFP_HELPER(tosiz, d)(float64 x, CPUState *env)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return vfp_itos(float64_to_int32_round_to_zero(x, &env->vfp.fp_status));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* floating point conversion */
 | 
				
			||||||
 | 
					float64 VFP_HELPER(fcvtd, s)(float32 x, CPUState *env)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return float32_to_float64(x, &env->vfp.fp_status);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					float32 VFP_HELPER(fcvts, d)(float64 x, CPUState *env)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return float64_to_float32(x, &env->vfp.fp_status);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* VFP3 fixed point conversion.  */
 | 
				
			||||||
 | 
					#define VFP_CONV_FIX(name, p, ftype, itype, sign) \
 | 
				
			||||||
 | 
					ftype VFP_HELPER(name##to, p)(ftype x, uint32_t shift, CPUState *env) \
 | 
				
			||||||
 | 
					{ \
 | 
				
			||||||
 | 
					    ftype tmp; \
 | 
				
			||||||
 | 
					    tmp = sign##int32_to_##ftype ((itype)vfp_##p##toi(x), \
 | 
				
			||||||
 | 
					                                  &env->vfp.fp_status); \
 | 
				
			||||||
 | 
					    return ftype##_scalbn(tmp, shift, &env->vfp.fp_status); \
 | 
				
			||||||
 | 
					} \
 | 
				
			||||||
 | 
					ftype VFP_HELPER(to##name, p)(ftype x, uint32_t shift, CPUState *env) \
 | 
				
			||||||
 | 
					{ \
 | 
				
			||||||
 | 
					    ftype tmp; \
 | 
				
			||||||
 | 
					    tmp = ftype##_scalbn(x, shift, &env->vfp.fp_status); \
 | 
				
			||||||
 | 
					    return vfp_ito##p((itype)ftype##_to_##sign##int32_round_to_zero(tmp, \
 | 
				
			||||||
 | 
					        &env->vfp.fp_status)); \
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					VFP_CONV_FIX(sh, d, float64, int16, )
 | 
				
			||||||
 | 
					VFP_CONV_FIX(sl, d, float64, int32, )
 | 
				
			||||||
 | 
					VFP_CONV_FIX(uh, d, float64, uint16, u)
 | 
				
			||||||
 | 
					VFP_CONV_FIX(ul, d, float64, uint32, u)
 | 
				
			||||||
 | 
					VFP_CONV_FIX(sh, s, float32, int16, )
 | 
				
			||||||
 | 
					VFP_CONV_FIX(sl, s, float32, int32, )
 | 
				
			||||||
 | 
					VFP_CONV_FIX(uh, s, float32, uint16, u)
 | 
				
			||||||
 | 
					VFP_CONV_FIX(ul, s, float32, uint32, u)
 | 
				
			||||||
 | 
					#undef VFP_CONV_FIX
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					float32 HELPER(recps_f32)(float32 a, float32 b, CPUState *env)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    float_status *s = &env->vfp.fp_status;
 | 
				
			||||||
 | 
					    float32 two = int32_to_float32(2, s);
 | 
				
			||||||
 | 
					    return float32_sub(two, float32_mul(a, b, s), s);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					float32 HELPER(rsqrts_f32)(float32 a, float32 b, CPUState *env)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    float_status *s = &env->vfp.fp_status;
 | 
				
			||||||
 | 
					    float32 three = int32_to_float32(3, s);
 | 
				
			||||||
 | 
					    return float32_sub(three, float32_mul(a, b, s), s);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* TODO: The architecture specifies the value that the estimate functions
 | 
				
			||||||
 | 
					   should return.  We return the exact reciprocal/root instead.  */
 | 
				
			||||||
 | 
					float32 HELPER(recpe_f32)(float32 a, CPUState *env)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    float_status *s = &env->vfp.fp_status;
 | 
				
			||||||
 | 
					    float32 one = int32_to_float32(1, s);
 | 
				
			||||||
 | 
					    return float32_div(one, a, s);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					float32 HELPER(rsqrte_f32)(float32 a, CPUState *env)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    float_status *s = &env->vfp.fp_status;
 | 
				
			||||||
 | 
					    float32 one = int32_to_float32(1, s);
 | 
				
			||||||
 | 
					    return float32_div(one, float32_sqrt(a, s), s);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint32_t HELPER(recpe_u32)(uint32_t a, CPUState *env)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    float_status *s = &env->vfp.fp_status;
 | 
				
			||||||
 | 
					    float32 tmp;
 | 
				
			||||||
 | 
					    tmp = int32_to_float32(a, s);
 | 
				
			||||||
 | 
					    tmp = float32_scalbn(tmp, -32, s);
 | 
				
			||||||
 | 
					    tmp = helper_recpe_f32(tmp, env);
 | 
				
			||||||
 | 
					    tmp = float32_scalbn(tmp, 31, s);
 | 
				
			||||||
 | 
					    return float32_to_int32(tmp, s);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint32_t HELPER(rsqrte_u32)(uint32_t a, CPUState *env)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    float_status *s = &env->vfp.fp_status;
 | 
				
			||||||
 | 
					    float32 tmp;
 | 
				
			||||||
 | 
					    tmp = int32_to_float32(a, s);
 | 
				
			||||||
 | 
					    tmp = float32_scalbn(tmp, -32, s);
 | 
				
			||||||
 | 
					    tmp = helper_rsqrte_f32(tmp, env);
 | 
				
			||||||
 | 
					    tmp = float32_scalbn(tmp, 31, s);
 | 
				
			||||||
 | 
					    return float32_to_int32(tmp, s);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -122,6 +122,69 @@ DEF_HELPER_0_3(set_r13_banked, void, (CPUState *, uint32_t, uint32_t))
 | 
				
			|||||||
DEF_HELPER_1_1(get_user_reg, uint32_t, (uint32_t))
 | 
					DEF_HELPER_1_1(get_user_reg, uint32_t, (uint32_t))
 | 
				
			||||||
DEF_HELPER_0_2(set_user_reg, void, (uint32_t, uint32_t))
 | 
					DEF_HELPER_0_2(set_user_reg, void, (uint32_t, uint32_t))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					DEF_HELPER_1_1(vfp_get_fpscr, uint32_t, (CPUState *))
 | 
				
			||||||
 | 
					DEF_HELPER_0_2(vfp_set_fpscr, void, (CPUState *, uint32_t))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					DEF_HELPER_1_3(vfp_adds, float32, (float32, float32, CPUState *))
 | 
				
			||||||
 | 
					DEF_HELPER_1_3(vfp_addd, float64, (float64, float64, CPUState *))
 | 
				
			||||||
 | 
					DEF_HELPER_1_3(vfp_subs, float32, (float32, float32, CPUState *))
 | 
				
			||||||
 | 
					DEF_HELPER_1_3(vfp_subd, float64, (float64, float64, CPUState *))
 | 
				
			||||||
 | 
					DEF_HELPER_1_3(vfp_muls, float32, (float32, float32, CPUState *))
 | 
				
			||||||
 | 
					DEF_HELPER_1_3(vfp_muld, float64, (float64, float64, CPUState *))
 | 
				
			||||||
 | 
					DEF_HELPER_1_3(vfp_divs, float32, (float32, float32, CPUState *))
 | 
				
			||||||
 | 
					DEF_HELPER_1_3(vfp_divd, float64, (float64, float64, CPUState *))
 | 
				
			||||||
 | 
					DEF_HELPER_1_1(vfp_negs, float32, (float32))
 | 
				
			||||||
 | 
					DEF_HELPER_1_1(vfp_negd, float64, (float64))
 | 
				
			||||||
 | 
					DEF_HELPER_1_1(vfp_abss, float32, (float32))
 | 
				
			||||||
 | 
					DEF_HELPER_1_1(vfp_absd, float64, (float64))
 | 
				
			||||||
 | 
					DEF_HELPER_1_2(vfp_sqrts, float32, (float32, CPUState *))
 | 
				
			||||||
 | 
					DEF_HELPER_1_2(vfp_sqrtd, float64, (float64, CPUState *))
 | 
				
			||||||
 | 
					DEF_HELPER_0_3(vfp_cmps, void, (float32, float32, CPUState *))
 | 
				
			||||||
 | 
					DEF_HELPER_0_3(vfp_cmpd, void, (float64, float64, CPUState *))
 | 
				
			||||||
 | 
					DEF_HELPER_0_3(vfp_cmpes, void, (float32, float32, CPUState *))
 | 
				
			||||||
 | 
					DEF_HELPER_0_3(vfp_cmped, void, (float64, float64, CPUState *))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					DEF_HELPER_1_2(vfp_fcvtds, float64, (float32, CPUState *))
 | 
				
			||||||
 | 
					DEF_HELPER_1_2(vfp_fcvtsd, float32, (float64, CPUState *))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					DEF_HELPER_1_2(vfp_uitos, float32, (float32, CPUState *))
 | 
				
			||||||
 | 
					DEF_HELPER_1_2(vfp_uitod, float64, (float32, CPUState *))
 | 
				
			||||||
 | 
					DEF_HELPER_1_2(vfp_sitos, float32, (float32, CPUState *))
 | 
				
			||||||
 | 
					DEF_HELPER_1_2(vfp_sitod, float64, (float32, CPUState *))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					DEF_HELPER_1_2(vfp_touis, float32, (float32, CPUState *))
 | 
				
			||||||
 | 
					DEF_HELPER_1_2(vfp_touid, float32, (float64, CPUState *))
 | 
				
			||||||
 | 
					DEF_HELPER_1_2(vfp_touizs, float32, (float32, CPUState *))
 | 
				
			||||||
 | 
					DEF_HELPER_1_2(vfp_touizd, float32, (float64, CPUState *))
 | 
				
			||||||
 | 
					DEF_HELPER_1_2(vfp_tosis, float32, (float32, CPUState *))
 | 
				
			||||||
 | 
					DEF_HELPER_1_2(vfp_tosid, float32, (float64, CPUState *))
 | 
				
			||||||
 | 
					DEF_HELPER_1_2(vfp_tosizs, float32, (float32, CPUState *))
 | 
				
			||||||
 | 
					DEF_HELPER_1_2(vfp_tosizd, float32, (float64, CPUState *))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					DEF_HELPER_1_3(vfp_toshs, float32, (float32, uint32_t, CPUState *))
 | 
				
			||||||
 | 
					DEF_HELPER_1_3(vfp_tosls, float32, (float32, uint32_t, CPUState *))
 | 
				
			||||||
 | 
					DEF_HELPER_1_3(vfp_touhs, float32, (float32, uint32_t, CPUState *))
 | 
				
			||||||
 | 
					DEF_HELPER_1_3(vfp_touls, float32, (float32, uint32_t, CPUState *))
 | 
				
			||||||
 | 
					DEF_HELPER_1_3(vfp_toshd, float64, (float64, uint32_t, CPUState *))
 | 
				
			||||||
 | 
					DEF_HELPER_1_3(vfp_tosld, float64, (float64, uint32_t, CPUState *))
 | 
				
			||||||
 | 
					DEF_HELPER_1_3(vfp_touhd, float64, (float64, uint32_t, CPUState *))
 | 
				
			||||||
 | 
					DEF_HELPER_1_3(vfp_tould, float64, (float64, uint32_t, CPUState *))
 | 
				
			||||||
 | 
					DEF_HELPER_1_3(vfp_shtos, float32, (float32, uint32_t, CPUState *))
 | 
				
			||||||
 | 
					DEF_HELPER_1_3(vfp_sltos, float32, (float32, uint32_t, CPUState *))
 | 
				
			||||||
 | 
					DEF_HELPER_1_3(vfp_uhtos, float32, (float32, uint32_t, CPUState *))
 | 
				
			||||||
 | 
					DEF_HELPER_1_3(vfp_ultos, float32, (float32, uint32_t, CPUState *))
 | 
				
			||||||
 | 
					DEF_HELPER_1_3(vfp_shtod, float64, (float64, uint32_t, CPUState *))
 | 
				
			||||||
 | 
					DEF_HELPER_1_3(vfp_sltod, float64, (float64, uint32_t, CPUState *))
 | 
				
			||||||
 | 
					DEF_HELPER_1_3(vfp_uhtod, float64, (float64, uint32_t, CPUState *))
 | 
				
			||||||
 | 
					DEF_HELPER_1_3(vfp_ultod, float64, (float64, uint32_t, CPUState *))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					DEF_HELPER_1_3(recps_f32, float32, (float32, float32, CPUState *))
 | 
				
			||||||
 | 
					DEF_HELPER_1_3(rsqrts_f32, float32, (float32, float32, CPUState *))
 | 
				
			||||||
 | 
					DEF_HELPER_1_2(recpe_f32, float32, (float32, CPUState *))
 | 
				
			||||||
 | 
					DEF_HELPER_1_2(rsqrte_f32, float32, (float32, CPUState *))
 | 
				
			||||||
 | 
					DEF_HELPER_1_2(recpe_u32, uint32_t, (uint32_t, CPUState *))
 | 
				
			||||||
 | 
					DEF_HELPER_1_2(rsqrte_u32, uint32_t, (uint32_t, CPUState *))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#undef DEF_HELPER
 | 
					#undef DEF_HELPER
 | 
				
			||||||
#undef DEF_HELPER_0_0
 | 
					#undef DEF_HELPER_0_0
 | 
				
			||||||
#undef DEF_HELPER_0_1
 | 
					#undef DEF_HELPER_0_1
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										313
									
								
								target-arm/op.c
									
									
									
									
									
								
							
							
						
						
									
										313
									
								
								target-arm/op.c
									
									
									
									
									
								
							@ -252,319 +252,6 @@ void OPPROTO op_rorl_T1_T0_cc(void)
 | 
				
			|||||||
    FORCE_RET();
 | 
					    FORCE_RET();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* VFP support.  We follow the convention used for VFP instrunctions:
 | 
					 | 
				
			||||||
   Single precition routines have a "s" suffix, double precision a
 | 
					 | 
				
			||||||
   "d" suffix.  */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define VFP_OP(name, p) void OPPROTO op_vfp_##name##p(void)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define VFP_BINOP(name) \
 | 
					 | 
				
			||||||
VFP_OP(name, s)             \
 | 
					 | 
				
			||||||
{                           \
 | 
					 | 
				
			||||||
    FT0s = float32_ ## name (FT0s, FT1s, &env->vfp.fp_status);    \
 | 
					 | 
				
			||||||
}                           \
 | 
					 | 
				
			||||||
VFP_OP(name, d)             \
 | 
					 | 
				
			||||||
{                           \
 | 
					 | 
				
			||||||
    FT0d = float64_ ## name (FT0d, FT1d, &env->vfp.fp_status);    \
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
VFP_BINOP(add)
 | 
					 | 
				
			||||||
VFP_BINOP(sub)
 | 
					 | 
				
			||||||
VFP_BINOP(mul)
 | 
					 | 
				
			||||||
VFP_BINOP(div)
 | 
					 | 
				
			||||||
#undef VFP_BINOP
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define VFP_HELPER(name)  \
 | 
					 | 
				
			||||||
VFP_OP(name, s)           \
 | 
					 | 
				
			||||||
{                         \
 | 
					 | 
				
			||||||
    do_vfp_##name##s();    \
 | 
					 | 
				
			||||||
}                         \
 | 
					 | 
				
			||||||
VFP_OP(name, d)           \
 | 
					 | 
				
			||||||
{                         \
 | 
					 | 
				
			||||||
    do_vfp_##name##d();    \
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
VFP_HELPER(abs)
 | 
					 | 
				
			||||||
VFP_HELPER(sqrt)
 | 
					 | 
				
			||||||
VFP_HELPER(cmp)
 | 
					 | 
				
			||||||
VFP_HELPER(cmpe)
 | 
					 | 
				
			||||||
#undef VFP_HELPER
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* XXX: Will this do the right thing for NANs.  Should invert the signbit
 | 
					 | 
				
			||||||
   without looking at the rest of the value.  */
 | 
					 | 
				
			||||||
VFP_OP(neg, s)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    FT0s = float32_chs(FT0s);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
VFP_OP(neg, d)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    FT0d = float64_chs(FT0d);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
VFP_OP(F1_ld0, s)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    union {
 | 
					 | 
				
			||||||
        uint32_t i;
 | 
					 | 
				
			||||||
        float32 s;
 | 
					 | 
				
			||||||
    } v;
 | 
					 | 
				
			||||||
    v.i = 0;
 | 
					 | 
				
			||||||
    FT1s = v.s;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
VFP_OP(F1_ld0, d)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    union {
 | 
					 | 
				
			||||||
        uint64_t i;
 | 
					 | 
				
			||||||
        float64 d;
 | 
					 | 
				
			||||||
    } v;
 | 
					 | 
				
			||||||
    v.i = 0;
 | 
					 | 
				
			||||||
    FT1d = v.d;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Helper routines to perform bitwise copies between float and int.  */
 | 
					 | 
				
			||||||
static inline float32 vfp_itos(uint32_t i)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    union {
 | 
					 | 
				
			||||||
        uint32_t i;
 | 
					 | 
				
			||||||
        float32 s;
 | 
					 | 
				
			||||||
    } v;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    v.i = i;
 | 
					 | 
				
			||||||
    return v.s;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static inline uint32_t vfp_stoi(float32 s)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    union {
 | 
					 | 
				
			||||||
        uint32_t i;
 | 
					 | 
				
			||||||
        float32 s;
 | 
					 | 
				
			||||||
    } v;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    v.s = s;
 | 
					 | 
				
			||||||
    return v.i;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static inline float64 vfp_itod(uint64_t i)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    union {
 | 
					 | 
				
			||||||
        uint64_t i;
 | 
					 | 
				
			||||||
        float64 d;
 | 
					 | 
				
			||||||
    } v;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    v.i = i;
 | 
					 | 
				
			||||||
    return v.d;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static inline uint64_t vfp_dtoi(float64 d)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    union {
 | 
					 | 
				
			||||||
        uint64_t i;
 | 
					 | 
				
			||||||
        float64 d;
 | 
					 | 
				
			||||||
    } v;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    v.d = d;
 | 
					 | 
				
			||||||
    return v.i;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Integer to float conversion.  */
 | 
					 | 
				
			||||||
VFP_OP(uito, s)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    FT0s = uint32_to_float32(vfp_stoi(FT0s), &env->vfp.fp_status);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
VFP_OP(uito, d)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    FT0d = uint32_to_float64(vfp_stoi(FT0s), &env->vfp.fp_status);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
VFP_OP(sito, s)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    FT0s = int32_to_float32(vfp_stoi(FT0s), &env->vfp.fp_status);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
VFP_OP(sito, d)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    FT0d = int32_to_float64(vfp_stoi(FT0s), &env->vfp.fp_status);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Float to integer conversion.  */
 | 
					 | 
				
			||||||
VFP_OP(toui, s)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    FT0s = vfp_itos(float32_to_uint32(FT0s, &env->vfp.fp_status));
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
VFP_OP(toui, d)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    FT0s = vfp_itos(float64_to_uint32(FT0d, &env->vfp.fp_status));
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
VFP_OP(tosi, s)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    FT0s = vfp_itos(float32_to_int32(FT0s, &env->vfp.fp_status));
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
VFP_OP(tosi, d)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    FT0s = vfp_itos(float64_to_int32(FT0d, &env->vfp.fp_status));
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* TODO: Set rounding mode properly.  */
 | 
					 | 
				
			||||||
VFP_OP(touiz, s)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    FT0s = vfp_itos(float32_to_uint32_round_to_zero(FT0s, &env->vfp.fp_status));
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
VFP_OP(touiz, d)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    FT0s = vfp_itos(float64_to_uint32_round_to_zero(FT0d, &env->vfp.fp_status));
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
VFP_OP(tosiz, s)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    FT0s = vfp_itos(float32_to_int32_round_to_zero(FT0s, &env->vfp.fp_status));
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
VFP_OP(tosiz, d)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    FT0s = vfp_itos(float64_to_int32_round_to_zero(FT0d, &env->vfp.fp_status));
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* floating point conversion */
 | 
					 | 
				
			||||||
VFP_OP(fcvtd, s)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    FT0d = float32_to_float64(FT0s, &env->vfp.fp_status);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
VFP_OP(fcvts, d)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    FT0s = float64_to_float32(FT0d, &env->vfp.fp_status);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* VFP3 fixed point conversion.  */
 | 
					 | 
				
			||||||
#define VFP_CONV_FIX(name, p, ftype, itype, sign) \
 | 
					 | 
				
			||||||
VFP_OP(name##to, p) \
 | 
					 | 
				
			||||||
{ \
 | 
					 | 
				
			||||||
    ftype tmp; \
 | 
					 | 
				
			||||||
    tmp = sign##int32_to_##ftype ((itype)vfp_##p##toi(FT0##p), \
 | 
					 | 
				
			||||||
                                  &env->vfp.fp_status); \
 | 
					 | 
				
			||||||
    FT0##p = ftype##_scalbn(tmp, PARAM1, &env->vfp.fp_status); \
 | 
					 | 
				
			||||||
} \
 | 
					 | 
				
			||||||
VFP_OP(to##name, p) \
 | 
					 | 
				
			||||||
{ \
 | 
					 | 
				
			||||||
    ftype tmp; \
 | 
					 | 
				
			||||||
    tmp = ftype##_scalbn(FT0##p, PARAM1, &env->vfp.fp_status); \
 | 
					 | 
				
			||||||
    FT0##p = vfp_ito##p((itype)ftype##_to_##sign##int32_round_to_zero(tmp, \
 | 
					 | 
				
			||||||
            &env->vfp.fp_status)); \
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
VFP_CONV_FIX(sh, d, float64, int16, )
 | 
					 | 
				
			||||||
VFP_CONV_FIX(sl, d, float64, int32, )
 | 
					 | 
				
			||||||
VFP_CONV_FIX(uh, d, float64, uint16, u)
 | 
					 | 
				
			||||||
VFP_CONV_FIX(ul, d, float64, uint32, u)
 | 
					 | 
				
			||||||
VFP_CONV_FIX(sh, s, float32, int16, )
 | 
					 | 
				
			||||||
VFP_CONV_FIX(sl, s, float32, int32, )
 | 
					 | 
				
			||||||
VFP_CONV_FIX(uh, s, float32, uint16, u)
 | 
					 | 
				
			||||||
VFP_CONV_FIX(ul, s, float32, uint32, u)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Get and Put values from registers.  */
 | 
					 | 
				
			||||||
VFP_OP(getreg_F0, d)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  FT0d = *(float64 *)((char *) env + PARAM1);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
VFP_OP(getreg_F0, s)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  FT0s = *(float32 *)((char *) env + PARAM1);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
VFP_OP(getreg_F1, d)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  FT1d = *(float64 *)((char *) env + PARAM1);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
VFP_OP(getreg_F1, s)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  FT1s = *(float32 *)((char *) env + PARAM1);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
VFP_OP(setreg_F0, d)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  *(float64 *)((char *) env + PARAM1) = FT0d;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
VFP_OP(setreg_F0, s)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  *(float32 *)((char *) env + PARAM1) = FT0s;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO op_vfp_movl_T0_fpscr(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    do_vfp_get_fpscr ();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO op_vfp_movl_T0_fpscr_flags(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    T0 = env->vfp.xregs[ARM_VFP_FPSCR] & (0xf << 28);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO op_vfp_movl_fpscr_T0(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    do_vfp_set_fpscr();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO op_vfp_movl_T0_xreg(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    T0 = env->vfp.xregs[PARAM1];
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO op_vfp_movl_xreg_T0(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    env->vfp.xregs[PARAM1] = T0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Move between FT0s to T0  */
 | 
					 | 
				
			||||||
void OPPROTO op_vfp_mrs(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    T0 = vfp_stoi(FT0s);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO op_vfp_msr(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    FT0s = vfp_itos(T0);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Move between FT0d and {T0,T1} */
 | 
					 | 
				
			||||||
void OPPROTO op_vfp_mrrd(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    CPU_DoubleU u;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    u.d = FT0d;
 | 
					 | 
				
			||||||
    T0 = u.l.lower;
 | 
					 | 
				
			||||||
    T1 = u.l.upper;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO op_vfp_mdrr(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    CPU_DoubleU u;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    u.l.lower = T0;
 | 
					 | 
				
			||||||
    u.l.upper = T1;
 | 
					 | 
				
			||||||
    FT0d = u.d;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Load immediate.  PARAM1 is the 32 most significant bits of the value.  */
 | 
					 | 
				
			||||||
void OPPROTO op_vfp_fconstd(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    CPU_DoubleU u;
 | 
					 | 
				
			||||||
    u.l.upper = PARAM1;
 | 
					 | 
				
			||||||
    u.l.lower = 0;
 | 
					 | 
				
			||||||
    FT0d = u.d;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO op_vfp_fconsts(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    FT0s = vfp_itos(PARAM1);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void OPPROTO op_movl_cp_T0(void)
 | 
					void OPPROTO op_movl_cp_T0(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    helper_set_cp(env, PARAM1, T0);
 | 
					    helper_set_cp(env, PARAM1, T0);
 | 
				
			||||||
 | 
				
			|||||||
@ -40,194 +40,6 @@ void cpu_unlock(void)
 | 
				
			|||||||
    spin_unlock(&global_cpu_lock);
 | 
					    spin_unlock(&global_cpu_lock);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* VFP support.  */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void do_vfp_abss(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    FT0s = float32_abs(FT0s);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void do_vfp_absd(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    FT0d = float64_abs(FT0d);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void do_vfp_sqrts(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    FT0s = float32_sqrt(FT0s, &env->vfp.fp_status);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void do_vfp_sqrtd(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    FT0d = float64_sqrt(FT0d, &env->vfp.fp_status);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* XXX: check quiet/signaling case */
 | 
					 | 
				
			||||||
#define DO_VFP_cmp(p, size)               \
 | 
					 | 
				
			||||||
void do_vfp_cmp##p(void)                  \
 | 
					 | 
				
			||||||
{                                         \
 | 
					 | 
				
			||||||
    uint32_t flags;                       \
 | 
					 | 
				
			||||||
    switch(float ## size ## _compare_quiet(FT0##p, FT1##p, &env->vfp.fp_status)) {\
 | 
					 | 
				
			||||||
    case 0: flags = 0x6; break;\
 | 
					 | 
				
			||||||
    case -1: flags = 0x8; break;\
 | 
					 | 
				
			||||||
    case 1: flags = 0x2; break;\
 | 
					 | 
				
			||||||
    default: case 2: flags = 0x3; break;\
 | 
					 | 
				
			||||||
    }\
 | 
					 | 
				
			||||||
    env->vfp.xregs[ARM_VFP_FPSCR] = (flags << 28)\
 | 
					 | 
				
			||||||
        | (env->vfp.xregs[ARM_VFP_FPSCR] & 0x0fffffff); \
 | 
					 | 
				
			||||||
    FORCE_RET();                          \
 | 
					 | 
				
			||||||
}\
 | 
					 | 
				
			||||||
\
 | 
					 | 
				
			||||||
void do_vfp_cmpe##p(void)                   \
 | 
					 | 
				
			||||||
{                                           \
 | 
					 | 
				
			||||||
    uint32_t flags;                       \
 | 
					 | 
				
			||||||
    switch(float ## size ## _compare(FT0##p, FT1##p, &env->vfp.fp_status)) {\
 | 
					 | 
				
			||||||
    case 0: flags = 0x6; break;\
 | 
					 | 
				
			||||||
    case -1: flags = 0x8; break;\
 | 
					 | 
				
			||||||
    case 1: flags = 0x2; break;\
 | 
					 | 
				
			||||||
    default: case 2: flags = 0x3; break;\
 | 
					 | 
				
			||||||
    }\
 | 
					 | 
				
			||||||
    env->vfp.xregs[ARM_VFP_FPSCR] = (flags << 28)\
 | 
					 | 
				
			||||||
        | (env->vfp.xregs[ARM_VFP_FPSCR] & 0x0fffffff); \
 | 
					 | 
				
			||||||
    FORCE_RET();                          \
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
DO_VFP_cmp(s, 32)
 | 
					 | 
				
			||||||
DO_VFP_cmp(d, 64)
 | 
					 | 
				
			||||||
#undef DO_VFP_cmp
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Convert host exception flags to vfp form.  */
 | 
					 | 
				
			||||||
static inline int vfp_exceptbits_from_host(int host_bits)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    int target_bits = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (host_bits & float_flag_invalid)
 | 
					 | 
				
			||||||
        target_bits |= 1;
 | 
					 | 
				
			||||||
    if (host_bits & float_flag_divbyzero)
 | 
					 | 
				
			||||||
        target_bits |= 2;
 | 
					 | 
				
			||||||
    if (host_bits & float_flag_overflow)
 | 
					 | 
				
			||||||
        target_bits |= 4;
 | 
					 | 
				
			||||||
    if (host_bits & float_flag_underflow)
 | 
					 | 
				
			||||||
        target_bits |= 8;
 | 
					 | 
				
			||||||
    if (host_bits & float_flag_inexact)
 | 
					 | 
				
			||||||
        target_bits |= 0x10;
 | 
					 | 
				
			||||||
    return target_bits;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Convert vfp exception flags to target form.  */
 | 
					 | 
				
			||||||
static inline int vfp_exceptbits_to_host(int target_bits)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    int host_bits = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (target_bits & 1)
 | 
					 | 
				
			||||||
        host_bits |= float_flag_invalid;
 | 
					 | 
				
			||||||
    if (target_bits & 2)
 | 
					 | 
				
			||||||
        host_bits |= float_flag_divbyzero;
 | 
					 | 
				
			||||||
    if (target_bits & 4)
 | 
					 | 
				
			||||||
        host_bits |= float_flag_overflow;
 | 
					 | 
				
			||||||
    if (target_bits & 8)
 | 
					 | 
				
			||||||
        host_bits |= float_flag_underflow;
 | 
					 | 
				
			||||||
    if (target_bits & 0x10)
 | 
					 | 
				
			||||||
        host_bits |= float_flag_inexact;
 | 
					 | 
				
			||||||
    return host_bits;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void do_vfp_set_fpscr(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    int i;
 | 
					 | 
				
			||||||
    uint32_t changed;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    changed = env->vfp.xregs[ARM_VFP_FPSCR];
 | 
					 | 
				
			||||||
    env->vfp.xregs[ARM_VFP_FPSCR] = (T0 & 0xffc8ffff);
 | 
					 | 
				
			||||||
    env->vfp.vec_len = (T0 >> 16) & 7;
 | 
					 | 
				
			||||||
    env->vfp.vec_stride = (T0 >> 20) & 3;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    changed ^= T0;
 | 
					 | 
				
			||||||
    if (changed & (3 << 22)) {
 | 
					 | 
				
			||||||
        i = (T0 >> 22) & 3;
 | 
					 | 
				
			||||||
        switch (i) {
 | 
					 | 
				
			||||||
        case 0:
 | 
					 | 
				
			||||||
            i = float_round_nearest_even;
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
        case 1:
 | 
					 | 
				
			||||||
            i = float_round_up;
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
        case 2:
 | 
					 | 
				
			||||||
            i = float_round_down;
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
        case 3:
 | 
					 | 
				
			||||||
            i = float_round_to_zero;
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        set_float_rounding_mode(i, &env->vfp.fp_status);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    i = vfp_exceptbits_to_host((T0 >> 8) & 0x1f);
 | 
					 | 
				
			||||||
    set_float_exception_flags(i, &env->vfp.fp_status);
 | 
					 | 
				
			||||||
    /* XXX: FZ and DN are not implemented.  */
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void do_vfp_get_fpscr(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    int i;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    T0 = (env->vfp.xregs[ARM_VFP_FPSCR] & 0xffc8ffff) | (env->vfp.vec_len << 16)
 | 
					 | 
				
			||||||
          | (env->vfp.vec_stride << 20);
 | 
					 | 
				
			||||||
    i = get_float_exception_flags(&env->vfp.fp_status);
 | 
					 | 
				
			||||||
    T0 |= vfp_exceptbits_from_host(i);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
float32 helper_recps_f32(float32 a, float32 b)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    float_status *s = &env->vfp.fp_status;
 | 
					 | 
				
			||||||
    float32 two = int32_to_float32(2, s);
 | 
					 | 
				
			||||||
    return float32_sub(two, float32_mul(a, b, s), s);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
float32 helper_rsqrts_f32(float32 a, float32 b)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    float_status *s = &env->vfp.fp_status;
 | 
					 | 
				
			||||||
    float32 three = int32_to_float32(3, s);
 | 
					 | 
				
			||||||
    return float32_sub(three, float32_mul(a, b, s), s);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* TODO: The architecture specifies the value that the estimate functions
 | 
					 | 
				
			||||||
   should return.  We return the exact reciprocal/root instead.  */
 | 
					 | 
				
			||||||
float32 helper_recpe_f32(float32 a)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    float_status *s = &env->vfp.fp_status;
 | 
					 | 
				
			||||||
    float32 one = int32_to_float32(1, s);
 | 
					 | 
				
			||||||
    return float32_div(one, a, s);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
float32 helper_rsqrte_f32(float32 a)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    float_status *s = &env->vfp.fp_status;
 | 
					 | 
				
			||||||
    float32 one = int32_to_float32(1, s);
 | 
					 | 
				
			||||||
    return float32_div(one, float32_sqrt(a, s), s);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
uint32_t helper_recpe_u32(uint32_t a)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    float_status *s = &env->vfp.fp_status;
 | 
					 | 
				
			||||||
    float32 tmp;
 | 
					 | 
				
			||||||
    tmp = int32_to_float32(a, s);
 | 
					 | 
				
			||||||
    tmp = float32_scalbn(tmp, -32, s);
 | 
					 | 
				
			||||||
    tmp = helper_recpe_f32(tmp);
 | 
					 | 
				
			||||||
    tmp = float32_scalbn(tmp, 31, s);
 | 
					 | 
				
			||||||
    return float32_to_int32(tmp, s);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
uint32_t helper_rsqrte_u32(uint32_t a)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    float_status *s = &env->vfp.fp_status;
 | 
					 | 
				
			||||||
    float32 tmp;
 | 
					 | 
				
			||||||
    tmp = int32_to_float32(a, s);
 | 
					 | 
				
			||||||
    tmp = float32_scalbn(tmp, -32, s);
 | 
					 | 
				
			||||||
    tmp = helper_rsqrte_f32(tmp);
 | 
					 | 
				
			||||||
    tmp = float32_scalbn(tmp, 31, s);
 | 
					 | 
				
			||||||
    return float32_to_int32(tmp, s);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void helper_neon_tbl(int rn, int maxindex)
 | 
					void helper_neon_tbl(int rn, int maxindex)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    uint32_t val;
 | 
					    uint32_t val;
 | 
				
			||||||
 | 
				
			|||||||
@ -77,24 +77,6 @@ void OPPROTO glue(op_stqex,MEMSUFFIX)(void)
 | 
				
			|||||||
    FORCE_RET();
 | 
					    FORCE_RET();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Floating point load/store.  Address is in T1 */
 | 
					 | 
				
			||||||
#define VFP_MEM_OP(p, w) \
 | 
					 | 
				
			||||||
void OPPROTO glue(op_vfp_ld##p,MEMSUFFIX)(void) \
 | 
					 | 
				
			||||||
{ \
 | 
					 | 
				
			||||||
    FT0##p = glue(ldf##w,MEMSUFFIX)(T1); \
 | 
					 | 
				
			||||||
    FORCE_RET(); \
 | 
					 | 
				
			||||||
} \
 | 
					 | 
				
			||||||
void OPPROTO glue(op_vfp_st##p,MEMSUFFIX)(void) \
 | 
					 | 
				
			||||||
{ \
 | 
					 | 
				
			||||||
    glue(stf##w,MEMSUFFIX)(T1, FT0##p); \
 | 
					 | 
				
			||||||
    FORCE_RET(); \
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
VFP_MEM_OP(s,l)
 | 
					 | 
				
			||||||
VFP_MEM_OP(d,q)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#undef VFP_MEM_OP
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* iwMMXt load/store.  Address is in T1 */
 | 
					/* iwMMXt load/store.  Address is in T1 */
 | 
				
			||||||
#define MMX_MEM_OP(name, ldname) \
 | 
					#define MMX_MEM_OP(name, ldname) \
 | 
				
			||||||
void OPPROTO glue(op_iwmmxt_ld##name,MEMSUFFIX)(void) \
 | 
					void OPPROTO glue(op_iwmmxt_ld##name,MEMSUFFIX)(void) \
 | 
				
			||||||
 | 
				
			|||||||
@ -14,6 +14,29 @@
 | 
				
			|||||||
#define NFS &env->vfp.fp_status
 | 
					#define NFS &env->vfp.fp_status
 | 
				
			||||||
#define NEON_OP(name) void OPPROTO op_neon_##name (void)
 | 
					#define NEON_OP(name) void OPPROTO op_neon_##name (void)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Helper routines to perform bitwise copies between float and int.  */
 | 
				
			||||||
 | 
					static inline float32 vfp_itos(uint32_t i)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    union {
 | 
				
			||||||
 | 
					        uint32_t i;
 | 
				
			||||||
 | 
					        float32 s;
 | 
				
			||||||
 | 
					    } v;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    v.i = i;
 | 
				
			||||||
 | 
					    return v.s;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline uint32_t vfp_stoi(float32 s)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    union {
 | 
				
			||||||
 | 
					        uint32_t i;
 | 
				
			||||||
 | 
					        float32 s;
 | 
				
			||||||
 | 
					    } v;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    v.s = s;
 | 
				
			||||||
 | 
					    return v.i;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
NEON_OP(getreg_T0)
 | 
					NEON_OP(getreg_T0)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    T0 = *(uint32_t *)((char *) env + PARAM1);
 | 
					    T0 = *(uint32_t *)((char *) env + PARAM1);
 | 
				
			||||||
@ -754,18 +777,6 @@ NEON_VOP(qrdmulh_s32, neon_s32, 1)
 | 
				
			|||||||
#undef NEON_FN
 | 
					#undef NEON_FN
 | 
				
			||||||
#undef NEON_QDMULH32
 | 
					#undef NEON_QDMULH32
 | 
				
			||||||
 | 
					
 | 
				
			||||||
NEON_OP(recps_f32)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    T0 = vfp_stoi(helper_recps_f32(vfp_itos(T0), vfp_itos(T1)));
 | 
					 | 
				
			||||||
    FORCE_RET();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
NEON_OP(rsqrts_f32)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    T0 = vfp_stoi(helper_rsqrts_f32(vfp_itos(T0), vfp_itos(T1)));
 | 
					 | 
				
			||||||
    FORCE_RET();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Floating point comparisons produce an integer result.  */
 | 
					/* Floating point comparisons produce an integer result.  */
 | 
				
			||||||
#define NEON_VOP_FCMP(name, cmp) \
 | 
					#define NEON_VOP_FCMP(name, cmp) \
 | 
				
			||||||
NEON_OP(name) \
 | 
					NEON_OP(name) \
 | 
				
			||||||
@ -1702,27 +1713,6 @@ NEON_OP(zip_u16)
 | 
				
			|||||||
    FORCE_RET();
 | 
					    FORCE_RET();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Reciprocal/root estimate.  */
 | 
					 | 
				
			||||||
NEON_OP(recpe_u32)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    T0 = helper_recpe_u32(T0);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
NEON_OP(rsqrte_u32)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    T0 = helper_rsqrte_u32(T0);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
NEON_OP(recpe_f32)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    FT0s = helper_recpe_f32(FT0s);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
NEON_OP(rsqrte_f32)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    FT0s = helper_rsqrte_f32(FT0s);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Table lookup.  This accessed the register file directly.  */
 | 
					/* Table lookup.  This accessed the register file directly.  */
 | 
				
			||||||
NEON_OP(tbl)
 | 
					NEON_OP(tbl)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
				
			|||||||
@ -79,6 +79,7 @@ extern int loglevel;
 | 
				
			|||||||
static TCGv cpu_env;
 | 
					static TCGv cpu_env;
 | 
				
			||||||
/* FIXME:  These should be removed.  */
 | 
					/* FIXME:  These should be removed.  */
 | 
				
			||||||
static TCGv cpu_T[3];
 | 
					static TCGv cpu_T[3];
 | 
				
			||||||
 | 
					static TCGv cpu_F0s, cpu_F1s, cpu_F0d, cpu_F1d;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* initialize TCG globals.  */
 | 
					/* initialize TCG globals.  */
 | 
				
			||||||
void arm_translate_init(void)
 | 
					void arm_translate_init(void)
 | 
				
			||||||
@ -959,16 +960,16 @@ static inline void gen_add_datah_offset(DisasContext *s, unsigned int insn,
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define VFP_OP(name)                      \
 | 
					#define VFP_OP2(name)                                                 \
 | 
				
			||||||
static inline void gen_vfp_##name(int dp)                             \
 | 
					static inline void gen_vfp_##name(int dp)                             \
 | 
				
			||||||
{                                                                     \
 | 
					{                                                                     \
 | 
				
			||||||
    if (dp)                                                           \
 | 
					    if (dp)                                                           \
 | 
				
			||||||
        gen_op_vfp_##name##d();           \
 | 
					        gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, cpu_env); \
 | 
				
			||||||
    else                                                              \
 | 
					    else                                                              \
 | 
				
			||||||
        gen_op_vfp_##name##s();           \
 | 
					        gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, cpu_env); \
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define VFP_OP1(name)                               \
 | 
					#define VFP_OP1i(name)                               \
 | 
				
			||||||
static inline void gen_vfp_##name(int dp, int arg)  \
 | 
					static inline void gen_vfp_##name(int dp, int arg)  \
 | 
				
			||||||
{                                                   \
 | 
					{                                                   \
 | 
				
			||||||
    if (dp)                                         \
 | 
					    if (dp)                                         \
 | 
				
			||||||
@ -977,55 +978,141 @@ static inline void gen_vfp_##name(int dp, int arg)  \
 | 
				
			|||||||
        gen_op_vfp_##name##s(arg);                  \
 | 
					        gen_op_vfp_##name##s(arg);                  \
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
VFP_OP(add)
 | 
					VFP_OP2(add)
 | 
				
			||||||
VFP_OP(sub)
 | 
					VFP_OP2(sub)
 | 
				
			||||||
VFP_OP(mul)
 | 
					VFP_OP2(mul)
 | 
				
			||||||
VFP_OP(div)
 | 
					VFP_OP2(div)
 | 
				
			||||||
VFP_OP(neg)
 | 
					 | 
				
			||||||
VFP_OP(abs)
 | 
					 | 
				
			||||||
VFP_OP(sqrt)
 | 
					 | 
				
			||||||
VFP_OP(cmp)
 | 
					 | 
				
			||||||
VFP_OP(cmpe)
 | 
					 | 
				
			||||||
VFP_OP(F1_ld0)
 | 
					 | 
				
			||||||
VFP_OP(uito)
 | 
					 | 
				
			||||||
VFP_OP(sito)
 | 
					 | 
				
			||||||
VFP_OP(toui)
 | 
					 | 
				
			||||||
VFP_OP(touiz)
 | 
					 | 
				
			||||||
VFP_OP(tosi)
 | 
					 | 
				
			||||||
VFP_OP(tosiz)
 | 
					 | 
				
			||||||
VFP_OP1(tosh)
 | 
					 | 
				
			||||||
VFP_OP1(tosl)
 | 
					 | 
				
			||||||
VFP_OP1(touh)
 | 
					 | 
				
			||||||
VFP_OP1(toul)
 | 
					 | 
				
			||||||
VFP_OP1(shto)
 | 
					 | 
				
			||||||
VFP_OP1(slto)
 | 
					 | 
				
			||||||
VFP_OP1(uhto)
 | 
					 | 
				
			||||||
VFP_OP1(ulto)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#undef VFP_OP
 | 
					#undef VFP_OP2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline void gen_vfp_fconst(int dp, uint32_t val)
 | 
					static inline void gen_vfp_abs(int dp)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    if (dp)
 | 
					    if (dp)
 | 
				
			||||||
        gen_op_vfp_fconstd(val);
 | 
					        gen_helper_vfp_absd(cpu_F0d, cpu_F0d);
 | 
				
			||||||
    else
 | 
					    else
 | 
				
			||||||
        gen_op_vfp_fconsts(val);
 | 
					        gen_helper_vfp_abss(cpu_F0s, cpu_F0s);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline void gen_vfp_neg(int dp)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if (dp)
 | 
				
			||||||
 | 
					        gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					        gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline void gen_vfp_sqrt(int dp)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if (dp)
 | 
				
			||||||
 | 
					        gen_helper_vfp_sqrtd(cpu_F0d, cpu_F0d, cpu_env);
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					        gen_helper_vfp_sqrts(cpu_F0s, cpu_F0s, cpu_env);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline void gen_vfp_cmp(int dp)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if (dp)
 | 
				
			||||||
 | 
					        gen_helper_vfp_cmpd(cpu_F0d, cpu_F1d, cpu_env);
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					        gen_helper_vfp_cmps(cpu_F0s, cpu_F1s, cpu_env);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline void gen_vfp_cmpe(int dp)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if (dp)
 | 
				
			||||||
 | 
					        gen_helper_vfp_cmped(cpu_F0d, cpu_F1d, cpu_env);
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					        gen_helper_vfp_cmpes(cpu_F0s, cpu_F1s, cpu_env);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline void gen_vfp_F1_ld0(int dp)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if (dp)
 | 
				
			||||||
 | 
					        tcg_gen_movi_i64(cpu_F0d, 0);
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					        tcg_gen_movi_i32(cpu_F0s, 0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline void gen_vfp_uito(int dp)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if (dp)
 | 
				
			||||||
 | 
					        gen_helper_vfp_uitod(cpu_F0d, cpu_F0s, cpu_env);
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					        gen_helper_vfp_uitos(cpu_F0s, cpu_F0s, cpu_env);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline void gen_vfp_sito(int dp)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if (dp)
 | 
				
			||||||
 | 
					        gen_helper_vfp_uitod(cpu_F0d, cpu_F0s, cpu_env);
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					        gen_helper_vfp_uitos(cpu_F0s, cpu_F0s, cpu_env);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline void gen_vfp_toui(int dp)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if (dp)
 | 
				
			||||||
 | 
					        gen_helper_vfp_touid(cpu_F0s, cpu_F0d, cpu_env);
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					        gen_helper_vfp_touis(cpu_F0s, cpu_F0s, cpu_env);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline void gen_vfp_touiz(int dp)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if (dp)
 | 
				
			||||||
 | 
					        gen_helper_vfp_touizd(cpu_F0s, cpu_F0d, cpu_env);
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					        gen_helper_vfp_touizs(cpu_F0s, cpu_F0s, cpu_env);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline void gen_vfp_tosi(int dp)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if (dp)
 | 
				
			||||||
 | 
					        gen_helper_vfp_tosid(cpu_F0s, cpu_F0d, cpu_env);
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					        gen_helper_vfp_tosis(cpu_F0s, cpu_F0s, cpu_env);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline void gen_vfp_tosiz(int dp)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if (dp)
 | 
				
			||||||
 | 
					        gen_helper_vfp_tosizd(cpu_F0s, cpu_F0d, cpu_env);
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					        gen_helper_vfp_tosizs(cpu_F0s, cpu_F0s, cpu_env);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define VFP_GEN_FIX(name) \
 | 
				
			||||||
 | 
					static inline void gen_vfp_##name(int dp, int shift) \
 | 
				
			||||||
 | 
					{ \
 | 
				
			||||||
 | 
					    if (dp) \
 | 
				
			||||||
 | 
					        gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, tcg_const_i32(shift), cpu_env);\
 | 
				
			||||||
 | 
					    else \
 | 
				
			||||||
 | 
					        gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, tcg_const_i32(shift), cpu_env);\
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					VFP_GEN_FIX(tosh)
 | 
				
			||||||
 | 
					VFP_GEN_FIX(tosl)
 | 
				
			||||||
 | 
					VFP_GEN_FIX(touh)
 | 
				
			||||||
 | 
					VFP_GEN_FIX(toul)
 | 
				
			||||||
 | 
					VFP_GEN_FIX(shto)
 | 
				
			||||||
 | 
					VFP_GEN_FIX(slto)
 | 
				
			||||||
 | 
					VFP_GEN_FIX(uhto)
 | 
				
			||||||
 | 
					VFP_GEN_FIX(ulto)
 | 
				
			||||||
 | 
					#undef VFP_GEN_FIX
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline void gen_vfp_ld(DisasContext *s, int dp)
 | 
					static inline void gen_vfp_ld(DisasContext *s, int dp)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    if (dp)
 | 
					    if (dp)
 | 
				
			||||||
        gen_ldst(vfp_ldd, s);
 | 
					        tcg_gen_qemu_ld64(cpu_F0d, cpu_T[1], IS_USER(s));
 | 
				
			||||||
    else
 | 
					    else
 | 
				
			||||||
        gen_ldst(vfp_lds, s);
 | 
					        tcg_gen_qemu_ld32u(cpu_F0s, cpu_T[1], IS_USER(s));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline void gen_vfp_st(DisasContext *s, int dp)
 | 
					static inline void gen_vfp_st(DisasContext *s, int dp)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    if (dp)
 | 
					    if (dp)
 | 
				
			||||||
        gen_ldst(vfp_std, s);
 | 
					        tcg_gen_qemu_st64(cpu_F0d, cpu_T[1], IS_USER(s));
 | 
				
			||||||
    else
 | 
					    else
 | 
				
			||||||
        gen_ldst(vfp_sts, s);
 | 
					        tcg_gen_qemu_st32(cpu_F0s, cpu_T[1], IS_USER(s));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline long
 | 
					static inline long
 | 
				
			||||||
@ -1055,28 +1142,33 @@ neon_reg_offset (int reg, int n)
 | 
				
			|||||||
#define NEON_GET_REG(T, reg, n) gen_op_neon_getreg_##T(neon_reg_offset(reg, n))
 | 
					#define NEON_GET_REG(T, reg, n) gen_op_neon_getreg_##T(neon_reg_offset(reg, n))
 | 
				
			||||||
#define NEON_SET_REG(T, reg, n) gen_op_neon_setreg_##T(neon_reg_offset(reg, n))
 | 
					#define NEON_SET_REG(T, reg, n) gen_op_neon_setreg_##T(neon_reg_offset(reg, n))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define tcg_gen_ld_f32 tcg_gen_ld_i32
 | 
				
			||||||
 | 
					#define tcg_gen_ld_f64 tcg_gen_ld_i64
 | 
				
			||||||
 | 
					#define tcg_gen_st_f32 tcg_gen_st_i32
 | 
				
			||||||
 | 
					#define tcg_gen_st_f64 tcg_gen_st_i64
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline void gen_mov_F0_vreg(int dp, int reg)
 | 
					static inline void gen_mov_F0_vreg(int dp, int reg)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    if (dp)
 | 
					    if (dp)
 | 
				
			||||||
        gen_op_vfp_getreg_F0d(vfp_reg_offset(dp, reg));
 | 
					        tcg_gen_ld_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
 | 
				
			||||||
    else
 | 
					    else
 | 
				
			||||||
        gen_op_vfp_getreg_F0s(vfp_reg_offset(dp, reg));
 | 
					        tcg_gen_ld_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline void gen_mov_F1_vreg(int dp, int reg)
 | 
					static inline void gen_mov_F1_vreg(int dp, int reg)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    if (dp)
 | 
					    if (dp)
 | 
				
			||||||
        gen_op_vfp_getreg_F1d(vfp_reg_offset(dp, reg));
 | 
					        tcg_gen_ld_f64(cpu_F1d, cpu_env, vfp_reg_offset(dp, reg));
 | 
				
			||||||
    else
 | 
					    else
 | 
				
			||||||
        gen_op_vfp_getreg_F1s(vfp_reg_offset(dp, reg));
 | 
					        tcg_gen_ld_f32(cpu_F1s, cpu_env, vfp_reg_offset(dp, reg));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline void gen_mov_vreg_F0(int dp, int reg)
 | 
					static inline void gen_mov_vreg_F0(int dp, int reg)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    if (dp)
 | 
					    if (dp)
 | 
				
			||||||
        gen_op_vfp_setreg_F0d(vfp_reg_offset(dp, reg));
 | 
					        tcg_gen_st_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
 | 
				
			||||||
    else
 | 
					    else
 | 
				
			||||||
        gen_op_vfp_setreg_F0s(vfp_reg_offset(dp, reg));
 | 
					        tcg_gen_st_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define ARM_CP_RW_BIT	(1 << 20)
 | 
					#define ARM_CP_RW_BIT	(1 << 20)
 | 
				
			||||||
@ -2262,6 +2354,20 @@ static int disas_cp15_insn(CPUState *env, DisasContext *s, uint32_t insn)
 | 
				
			|||||||
#define VFP_SREG_M(insn) VFP_SREG(insn,  0,  5)
 | 
					#define VFP_SREG_M(insn) VFP_SREG(insn,  0,  5)
 | 
				
			||||||
#define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn,  0,  5)
 | 
					#define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn,  0,  5)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Move between integer and VFP cores.  */
 | 
				
			||||||
 | 
					static TCGv gen_vfp_mrs(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    TCGv tmp = new_tmp();
 | 
				
			||||||
 | 
					    tcg_gen_mov_i32(tmp, cpu_F0s);
 | 
				
			||||||
 | 
					    return tmp;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void gen_vfp_msr(TCGv tmp)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    tcg_gen_mov_i32(cpu_F0s, tmp);
 | 
				
			||||||
 | 
					    dead_tmp(tmp);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline int
 | 
					static inline int
 | 
				
			||||||
vfp_enabled(CPUState * env)
 | 
					vfp_enabled(CPUState * env)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@ -2274,6 +2380,7 @@ static int disas_vfp_insn(CPUState * env, DisasContext *s, uint32_t insn)
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    uint32_t rd, rn, rm, op, i, n, offset, delta_d, delta_m, bank_mask;
 | 
					    uint32_t rd, rn, rm, op, i, n, offset, delta_d, delta_m, bank_mask;
 | 
				
			||||||
    int dp, veclen;
 | 
					    int dp, veclen;
 | 
				
			||||||
 | 
					    TCGv tmp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!arm_feature(env, ARM_FEATURE_VFP))
 | 
					    if (!arm_feature(env, ARM_FEATURE_VFP))
 | 
				
			||||||
        return 1;
 | 
					        return 1;
 | 
				
			||||||
@ -2396,18 +2503,18 @@ static int disas_vfp_insn(CPUState * env, DisasContext *s, uint32_t insn)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                        switch (rn) {
 | 
					                        switch (rn) {
 | 
				
			||||||
                        case ARM_VFP_FPSID:
 | 
					                        case ARM_VFP_FPSID:
 | 
				
			||||||
                            /* VFP2 allows access for FSID from userspace.
 | 
					                            /* VFP2 allows access to FSID from userspace.
 | 
				
			||||||
                               VFP3 restricts all id registers to privileged
 | 
					                               VFP3 restricts all id registers to privileged
 | 
				
			||||||
                               accesses.  */
 | 
					                               accesses.  */
 | 
				
			||||||
                            if (IS_USER(s)
 | 
					                            if (IS_USER(s)
 | 
				
			||||||
                                && arm_feature(env, ARM_FEATURE_VFP3))
 | 
					                                && arm_feature(env, ARM_FEATURE_VFP3))
 | 
				
			||||||
                                return 1;
 | 
					                                return 1;
 | 
				
			||||||
                            gen_op_vfp_movl_T0_xreg(rn);
 | 
					                            tmp = load_cpu_field(vfp.xregs[rn]);
 | 
				
			||||||
                            break;
 | 
					                            break;
 | 
				
			||||||
                        case ARM_VFP_FPEXC:
 | 
					                        case ARM_VFP_FPEXC:
 | 
				
			||||||
                            if (IS_USER(s))
 | 
					                            if (IS_USER(s))
 | 
				
			||||||
                                return 1;
 | 
					                                return 1;
 | 
				
			||||||
                            gen_op_vfp_movl_T0_xreg(rn);
 | 
					                            tmp = load_cpu_field(vfp.xregs[rn]);
 | 
				
			||||||
                            break;
 | 
					                            break;
 | 
				
			||||||
                        case ARM_VFP_FPINST:
 | 
					                        case ARM_VFP_FPINST:
 | 
				
			||||||
                        case ARM_VFP_FPINST2:
 | 
					                        case ARM_VFP_FPINST2:
 | 
				
			||||||
@ -2415,36 +2522,41 @@ static int disas_vfp_insn(CPUState * env, DisasContext *s, uint32_t insn)
 | 
				
			|||||||
                            if (IS_USER(s)
 | 
					                            if (IS_USER(s)
 | 
				
			||||||
                                || arm_feature(env, ARM_FEATURE_VFP3))
 | 
					                                || arm_feature(env, ARM_FEATURE_VFP3))
 | 
				
			||||||
                                return 1;
 | 
					                                return 1;
 | 
				
			||||||
                            gen_op_vfp_movl_T0_xreg(rn);
 | 
					                            tmp = load_cpu_field(vfp.xregs[rn]);
 | 
				
			||||||
                            break;
 | 
					                            break;
 | 
				
			||||||
                        case ARM_VFP_FPSCR:
 | 
					                        case ARM_VFP_FPSCR:
 | 
				
			||||||
			    if (rd == 15)
 | 
								    if (rd == 15) {
 | 
				
			||||||
				gen_op_vfp_movl_T0_fpscr_flags();
 | 
					                                tmp = load_cpu_field(vfp.xregs[ARM_VFP_FPSCR]);
 | 
				
			||||||
			    else
 | 
					                                tcg_gen_andi_i32(tmp, tmp, 0xf0000000);
 | 
				
			||||||
				gen_op_vfp_movl_T0_fpscr();
 | 
					                            } else {
 | 
				
			||||||
 | 
					                                tmp = new_tmp();
 | 
				
			||||||
 | 
					                                gen_helper_vfp_get_fpscr(tmp, cpu_env);
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
                            break;
 | 
					                            break;
 | 
				
			||||||
                        case ARM_VFP_MVFR0:
 | 
					                        case ARM_VFP_MVFR0:
 | 
				
			||||||
                        case ARM_VFP_MVFR1:
 | 
					                        case ARM_VFP_MVFR1:
 | 
				
			||||||
                            if (IS_USER(s)
 | 
					                            if (IS_USER(s)
 | 
				
			||||||
                                || !arm_feature(env, ARM_FEATURE_VFP3))
 | 
					                                || !arm_feature(env, ARM_FEATURE_VFP3))
 | 
				
			||||||
                                return 1;
 | 
					                                return 1;
 | 
				
			||||||
                            gen_op_vfp_movl_T0_xreg(rn);
 | 
					                            tmp = load_cpu_field(vfp.xregs[rn]);
 | 
				
			||||||
                            break;
 | 
					                            break;
 | 
				
			||||||
                        default:
 | 
					                        default:
 | 
				
			||||||
                            return 1;
 | 
					                            return 1;
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                    } else {
 | 
					                    } else {
 | 
				
			||||||
                        gen_mov_F0_vreg(0, rn);
 | 
					                        gen_mov_F0_vreg(0, rn);
 | 
				
			||||||
                        gen_op_vfp_mrs();
 | 
					                        tmp = gen_vfp_mrs();
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                    if (rd == 15) {
 | 
					                    if (rd == 15) {
 | 
				
			||||||
                        /* Set the 4 flag bits in the CPSR.  */
 | 
					                        /* Set the 4 flag bits in the CPSR.  */
 | 
				
			||||||
                        gen_set_nzcv(cpu_T[0]);
 | 
					                        gen_set_nzcv(tmp);
 | 
				
			||||||
                    } else
 | 
					                        dead_tmp(tmp);
 | 
				
			||||||
                        gen_movl_reg_T0(s, rd);
 | 
					                    } else {
 | 
				
			||||||
 | 
					                        store_reg(s, rd, tmp);
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
                } else {
 | 
					                } else {
 | 
				
			||||||
                    /* arm->vfp */
 | 
					                    /* arm->vfp */
 | 
				
			||||||
                    gen_movl_T0_reg(s, rd);
 | 
					                    tmp = load_reg(s, rd);
 | 
				
			||||||
                    if (insn & (1 << 21)) {
 | 
					                    if (insn & (1 << 21)) {
 | 
				
			||||||
                        rn >>= 1;
 | 
					                        rn >>= 1;
 | 
				
			||||||
                        /* system register */
 | 
					                        /* system register */
 | 
				
			||||||
@ -2455,24 +2567,25 @@ static int disas_vfp_insn(CPUState * env, DisasContext *s, uint32_t insn)
 | 
				
			|||||||
                            /* Writes are ignored.  */
 | 
					                            /* Writes are ignored.  */
 | 
				
			||||||
                            break;
 | 
					                            break;
 | 
				
			||||||
                        case ARM_VFP_FPSCR:
 | 
					                        case ARM_VFP_FPSCR:
 | 
				
			||||||
                            gen_op_vfp_movl_fpscr_T0();
 | 
					                            gen_helper_vfp_set_fpscr(cpu_env, tmp);
 | 
				
			||||||
 | 
					                            dead_tmp(tmp);
 | 
				
			||||||
                            gen_lookup_tb(s);
 | 
					                            gen_lookup_tb(s);
 | 
				
			||||||
                            break;
 | 
					                            break;
 | 
				
			||||||
                        case ARM_VFP_FPEXC:
 | 
					                        case ARM_VFP_FPEXC:
 | 
				
			||||||
                            if (IS_USER(s))
 | 
					                            if (IS_USER(s))
 | 
				
			||||||
                                return 1;
 | 
					                                return 1;
 | 
				
			||||||
                            gen_op_vfp_movl_xreg_T0(rn);
 | 
					                            store_cpu_field(tmp, vfp.xregs[rn]);
 | 
				
			||||||
                            gen_lookup_tb(s);
 | 
					                            gen_lookup_tb(s);
 | 
				
			||||||
                            break;
 | 
					                            break;
 | 
				
			||||||
                        case ARM_VFP_FPINST:
 | 
					                        case ARM_VFP_FPINST:
 | 
				
			||||||
                        case ARM_VFP_FPINST2:
 | 
					                        case ARM_VFP_FPINST2:
 | 
				
			||||||
                            gen_op_vfp_movl_xreg_T0(rn);
 | 
					                            store_cpu_field(tmp, vfp.xregs[rn]);
 | 
				
			||||||
                            break;
 | 
					                            break;
 | 
				
			||||||
                        default:
 | 
					                        default:
 | 
				
			||||||
                            return 1;
 | 
					                            return 1;
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                    } else {
 | 
					                    } else {
 | 
				
			||||||
                        gen_op_vfp_msr();
 | 
					                        gen_vfp_msr(tmp);
 | 
				
			||||||
                        gen_mov_vreg_F0(0, rn);
 | 
					                        gen_mov_vreg_F0(0, rn);
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
@ -2640,14 +2753,15 @@ static int disas_vfp_insn(CPUState * env, DisasContext *s, uint32_t insn)
 | 
				
			|||||||
                        else
 | 
					                        else
 | 
				
			||||||
                            i |= 0x4000;
 | 
					                            i |= 0x4000;
 | 
				
			||||||
                        n |= i << 16;
 | 
					                        n |= i << 16;
 | 
				
			||||||
 | 
					                        tcg_gen_movi_i64(cpu_F0d, ((uint64_t)n) << 32);
 | 
				
			||||||
                    } else {
 | 
					                    } else {
 | 
				
			||||||
                        if (i & 0x40)
 | 
					                        if (i & 0x40)
 | 
				
			||||||
                            i |= 0x780;
 | 
					                            i |= 0x780;
 | 
				
			||||||
                        else
 | 
					                        else
 | 
				
			||||||
                            i |= 0x800;
 | 
					                            i |= 0x800;
 | 
				
			||||||
                        n |= i << 19;
 | 
					                        n |= i << 19;
 | 
				
			||||||
 | 
					                        tcg_gen_movi_i32(cpu_F0d, ((uint64_t)n) << 32);
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                    gen_vfp_fconst(dp, n);
 | 
					 | 
				
			||||||
                    break;
 | 
					                    break;
 | 
				
			||||||
                case 15: /* extension space */
 | 
					                case 15: /* extension space */
 | 
				
			||||||
                    switch (rn) {
 | 
					                    switch (rn) {
 | 
				
			||||||
@ -2678,9 +2792,9 @@ static int disas_vfp_insn(CPUState * env, DisasContext *s, uint32_t insn)
 | 
				
			|||||||
                        break;
 | 
					                        break;
 | 
				
			||||||
                    case 15: /* single<->double conversion */
 | 
					                    case 15: /* single<->double conversion */
 | 
				
			||||||
                        if (dp)
 | 
					                        if (dp)
 | 
				
			||||||
                            gen_op_vfp_fcvtsd();
 | 
					                            gen_helper_vfp_fcvtsd(cpu_F0s, cpu_F0d, cpu_env);
 | 
				
			||||||
                        else
 | 
					                        else
 | 
				
			||||||
                            gen_op_vfp_fcvtds();
 | 
					                            gen_helper_vfp_fcvtds(cpu_F0d, cpu_F0s, cpu_env);
 | 
				
			||||||
                        break;
 | 
					                        break;
 | 
				
			||||||
                    case 16: /* fuito */
 | 
					                    case 16: /* fuito */
 | 
				
			||||||
                        gen_vfp_uito(dp);
 | 
					                        gen_vfp_uito(dp);
 | 
				
			||||||
@ -2814,31 +2928,35 @@ static int disas_vfp_insn(CPUState * env, DisasContext *s, uint32_t insn)
 | 
				
			|||||||
            if (insn & ARM_CP_RW_BIT) {
 | 
					            if (insn & ARM_CP_RW_BIT) {
 | 
				
			||||||
                /* vfp->arm */
 | 
					                /* vfp->arm */
 | 
				
			||||||
                if (dp) {
 | 
					                if (dp) {
 | 
				
			||||||
                    gen_mov_F0_vreg(1, rm);
 | 
					                    gen_mov_F0_vreg(0, rm * 2);
 | 
				
			||||||
                    gen_op_vfp_mrrd();
 | 
					                    tmp = gen_vfp_mrs();
 | 
				
			||||||
                    gen_movl_reg_T0(s, rd);
 | 
					                    store_reg(s, rd, tmp);
 | 
				
			||||||
                    gen_movl_reg_T1(s, rn);
 | 
					                    gen_mov_F0_vreg(0, rm * 2 + 1);
 | 
				
			||||||
 | 
					                    tmp = gen_vfp_mrs();
 | 
				
			||||||
 | 
					                    store_reg(s, rn, tmp);
 | 
				
			||||||
                } else {
 | 
					                } else {
 | 
				
			||||||
                    gen_mov_F0_vreg(0, rm);
 | 
					                    gen_mov_F0_vreg(0, rm);
 | 
				
			||||||
                    gen_op_vfp_mrs();
 | 
					                    tmp = gen_vfp_mrs();
 | 
				
			||||||
                    gen_movl_reg_T0(s, rn);
 | 
					                    store_reg(s, rn, tmp);
 | 
				
			||||||
                    gen_mov_F0_vreg(0, rm + 1);
 | 
					                    gen_mov_F0_vreg(0, rm + 1);
 | 
				
			||||||
                    gen_op_vfp_mrs();
 | 
					                    tmp = gen_vfp_mrs();
 | 
				
			||||||
                    gen_movl_reg_T0(s, rd);
 | 
					                    store_reg(s, rd, tmp);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
                /* arm->vfp */
 | 
					                /* arm->vfp */
 | 
				
			||||||
                if (dp) {
 | 
					                if (dp) {
 | 
				
			||||||
                    gen_movl_T0_reg(s, rd);
 | 
					                    tmp = load_reg(s, rd);
 | 
				
			||||||
                    gen_movl_T1_reg(s, rn);
 | 
					                    gen_vfp_msr(tmp);
 | 
				
			||||||
                    gen_op_vfp_mdrr();
 | 
					                    gen_mov_vreg_F0(0, rm * 2);
 | 
				
			||||||
                    gen_mov_vreg_F0(1, rm);
 | 
					                    tmp = load_reg(s, rn);
 | 
				
			||||||
 | 
					                    gen_vfp_msr(tmp);
 | 
				
			||||||
 | 
					                    gen_mov_vreg_F0(0, rm * 2 + 1);
 | 
				
			||||||
                } else {
 | 
					                } else {
 | 
				
			||||||
                    gen_movl_T0_reg(s, rn);
 | 
					                    tmp = load_reg(s, rn);
 | 
				
			||||||
                    gen_op_vfp_msr();
 | 
					                    gen_vfp_msr(tmp);
 | 
				
			||||||
                    gen_mov_vreg_F0(0, rm);
 | 
					                    gen_mov_vreg_F0(0, rm);
 | 
				
			||||||
                    gen_movl_T0_reg(s, rd);
 | 
					                    tmp = load_reg(s, rd);
 | 
				
			||||||
                    gen_op_vfp_msr();
 | 
					                    gen_vfp_msr(tmp);
 | 
				
			||||||
                    gen_mov_vreg_F0(0, rm + 1);
 | 
					                    gen_mov_vreg_F0(0, rm + 1);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
@ -3993,9 +4111,9 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
 | 
				
			|||||||
            break;
 | 
					            break;
 | 
				
			||||||
        case 31:
 | 
					        case 31:
 | 
				
			||||||
            if (size == 0)
 | 
					            if (size == 0)
 | 
				
			||||||
                gen_op_neon_recps_f32();
 | 
					                gen_helper_recps_f32(cpu_T[0], cpu_T[0], cpu_T[1], cpu_env);
 | 
				
			||||||
            else
 | 
					            else
 | 
				
			||||||
                gen_op_neon_rsqrts_f32();
 | 
					                gen_helper_rsqrts_f32(cpu_T[0], cpu_T[0], cpu_T[1], cpu_env);
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
        default:
 | 
					        default:
 | 
				
			||||||
            abort();
 | 
					            abort();
 | 
				
			||||||
@ -4242,19 +4360,19 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
 | 
				
			|||||||
            } else if (op == 15 || op == 16) {
 | 
					            } else if (op == 15 || op == 16) {
 | 
				
			||||||
                /* VCVT fixed-point.  */
 | 
					                /* VCVT fixed-point.  */
 | 
				
			||||||
                for (pass = 0; pass < (q ? 4 : 2); pass++) {
 | 
					                for (pass = 0; pass < (q ? 4 : 2); pass++) {
 | 
				
			||||||
                    gen_op_vfp_getreg_F0s(neon_reg_offset(rm, pass));
 | 
					                    tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, pass));
 | 
				
			||||||
                    if (op & 1) {
 | 
					                    if (op & 1) {
 | 
				
			||||||
                        if (u)
 | 
					                        if (u)
 | 
				
			||||||
                            gen_op_vfp_ultos(shift);
 | 
					                            gen_vfp_ulto(0, shift);
 | 
				
			||||||
                        else
 | 
					                        else
 | 
				
			||||||
                            gen_op_vfp_sltos(shift);
 | 
					                            gen_vfp_slto(0, shift);
 | 
				
			||||||
                    } else {
 | 
					                    } else {
 | 
				
			||||||
                        if (u)
 | 
					                        if (u)
 | 
				
			||||||
                            gen_op_vfp_touls(shift);
 | 
					                            gen_vfp_toul(0, shift);
 | 
				
			||||||
                        else
 | 
					                        else
 | 
				
			||||||
                            gen_op_vfp_tosls(shift);
 | 
					                            gen_vfp_tosl(0, shift);
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                    gen_op_vfp_setreg_F0s(neon_reg_offset(rd, pass));
 | 
					                    tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, pass));
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
                return 1;
 | 
					                return 1;
 | 
				
			||||||
@ -4898,7 +5016,8 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
 | 
				
			|||||||
                elementwise:
 | 
					                elementwise:
 | 
				
			||||||
                    for (pass = 0; pass < (q ? 4 : 2); pass++) {
 | 
					                    for (pass = 0; pass < (q ? 4 : 2); pass++) {
 | 
				
			||||||
                        if (op == 30 || op == 31 || op >= 58) {
 | 
					                        if (op == 30 || op == 31 || op >= 58) {
 | 
				
			||||||
                            gen_op_vfp_getreg_F0s(neon_reg_offset(rm, pass));
 | 
					                            tcg_gen_ld_f32(cpu_F0s, cpu_env,
 | 
				
			||||||
 | 
					                                           neon_reg_offset(rm, pass));
 | 
				
			||||||
                        } else {
 | 
					                        } else {
 | 
				
			||||||
                            NEON_GET_REG(T0, rm, pass);
 | 
					                            NEON_GET_REG(T0, rm, pass);
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
@ -5041,10 +5160,10 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
 | 
				
			|||||||
                            gen_op_neon_ceq_f32();
 | 
					                            gen_op_neon_ceq_f32();
 | 
				
			||||||
                            break;
 | 
					                            break;
 | 
				
			||||||
                        case 30: /* Float VABS */
 | 
					                        case 30: /* Float VABS */
 | 
				
			||||||
                            gen_op_vfp_abss();
 | 
					                            gen_vfp_abs(0);
 | 
				
			||||||
                            break;
 | 
					                            break;
 | 
				
			||||||
                        case 31: /* Float VNEG */
 | 
					                        case 31: /* Float VNEG */
 | 
				
			||||||
                            gen_op_vfp_negs();
 | 
					                            gen_vfp_neg(0);
 | 
				
			||||||
                            break;
 | 
					                            break;
 | 
				
			||||||
                        case 32: /* VSWP */
 | 
					                        case 32: /* VSWP */
 | 
				
			||||||
                            NEON_GET_REG(T1, rd, pass);
 | 
					                            NEON_GET_REG(T1, rd, pass);
 | 
				
			||||||
@ -5061,35 +5180,36 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
 | 
				
			|||||||
                            NEON_SET_REG(T1, rm, pass);
 | 
					                            NEON_SET_REG(T1, rm, pass);
 | 
				
			||||||
                            break;
 | 
					                            break;
 | 
				
			||||||
                        case 56: /* Integer VRECPE */
 | 
					                        case 56: /* Integer VRECPE */
 | 
				
			||||||
                            gen_op_neon_recpe_u32();
 | 
					                            gen_helper_recpe_u32(cpu_T[0], cpu_T[0], cpu_env);
 | 
				
			||||||
                            break;
 | 
					                            break;
 | 
				
			||||||
                        case 57: /* Integer VRSQRTE */
 | 
					                        case 57: /* Integer VRSQRTE */
 | 
				
			||||||
                            gen_op_neon_rsqrte_u32();
 | 
					                            gen_helper_rsqrte_u32(cpu_T[0], cpu_T[0], cpu_env);
 | 
				
			||||||
                            break;
 | 
					                            break;
 | 
				
			||||||
                        case 58: /* Float VRECPE */
 | 
					                        case 58: /* Float VRECPE */
 | 
				
			||||||
                            gen_op_neon_recpe_f32();
 | 
					                            gen_helper_recpe_f32(cpu_F0s, cpu_F0s, cpu_env);
 | 
				
			||||||
                            break;
 | 
					                            break;
 | 
				
			||||||
                        case 59: /* Float VRSQRTE */
 | 
					                        case 59: /* Float VRSQRTE */
 | 
				
			||||||
                            gen_op_neon_rsqrte_f32();
 | 
					                            gen_helper_rsqrte_f32(cpu_F0s, cpu_F0s, cpu_env);
 | 
				
			||||||
                            break;
 | 
					                            break;
 | 
				
			||||||
                        case 60: /* VCVT.F32.S32 */
 | 
					                        case 60: /* VCVT.F32.S32 */
 | 
				
			||||||
                            gen_op_vfp_tosizs();
 | 
					                            gen_vfp_tosiz(0);
 | 
				
			||||||
                            break;
 | 
					                            break;
 | 
				
			||||||
                        case 61: /* VCVT.F32.U32 */
 | 
					                        case 61: /* VCVT.F32.U32 */
 | 
				
			||||||
                            gen_op_vfp_touizs();
 | 
					                            gen_vfp_touiz(0);
 | 
				
			||||||
                            break;
 | 
					                            break;
 | 
				
			||||||
                        case 62: /* VCVT.S32.F32 */
 | 
					                        case 62: /* VCVT.S32.F32 */
 | 
				
			||||||
                            gen_op_vfp_sitos();
 | 
					                            gen_vfp_sito(0);
 | 
				
			||||||
                            break;
 | 
					                            break;
 | 
				
			||||||
                        case 63: /* VCVT.U32.F32 */
 | 
					                        case 63: /* VCVT.U32.F32 */
 | 
				
			||||||
                            gen_op_vfp_uitos();
 | 
					                            gen_vfp_uito(0);
 | 
				
			||||||
                            break;
 | 
					                            break;
 | 
				
			||||||
                        default:
 | 
					                        default:
 | 
				
			||||||
                            /* Reserved: 21, 29, 39-56 */
 | 
					                            /* Reserved: 21, 29, 39-56 */
 | 
				
			||||||
                            return 1;
 | 
					                            return 1;
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                        if (op == 30 || op == 31 || op >= 58) {
 | 
					                        if (op == 30 || op == 31 || op >= 58) {
 | 
				
			||||||
                            gen_op_vfp_setreg_F0s(neon_reg_offset(rm, pass));
 | 
					                            tcg_gen_st_f32(cpu_F0s, cpu_env,
 | 
				
			||||||
 | 
					                                           neon_reg_offset(rd, pass));
 | 
				
			||||||
                        } else {
 | 
					                        } else {
 | 
				
			||||||
                            NEON_SET_REG(T0, rd, pass);
 | 
					                            NEON_SET_REG(T0, rd, pass);
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
@ -8062,6 +8182,10 @@ static inline int gen_intermediate_code_internal(CPUState *env,
 | 
				
			|||||||
        dc->user = (env->uncached_cpsr & 0x1f) == ARM_CPU_MODE_USR;
 | 
					        dc->user = (env->uncached_cpsr & 0x1f) == ARM_CPU_MODE_USR;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					    cpu_F0s = tcg_temp_new(TCG_TYPE_I32);
 | 
				
			||||||
 | 
					    cpu_F1s = tcg_temp_new(TCG_TYPE_I32);
 | 
				
			||||||
 | 
					    cpu_F0d = tcg_temp_new(TCG_TYPE_I64);
 | 
				
			||||||
 | 
					    cpu_F1d = tcg_temp_new(TCG_TYPE_I64);
 | 
				
			||||||
    next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
 | 
					    next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
 | 
				
			||||||
    lj = -1;
 | 
					    lj = -1;
 | 
				
			||||||
    /* Reset the conditional execution bits immediately. This avoids
 | 
					    /* Reset the conditional execution bits immediately. This avoids
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user