Alpha architecture emulation core.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2597 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
parent
6fa4cea9e8
commit
4c9649a967
385
target-alpha/cpu.h
Normal file
385
target-alpha/cpu.h
Normal file
@ -0,0 +1,385 @@
|
||||
/*
|
||||
* Alpha emulation cpu definitions for qemu.
|
||||
*
|
||||
* Copyright (c) 2007 Jocelyn Mayer
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#if !defined (__CPU_ALPHA_H__)
|
||||
#define __CPU_ALPHA_H__
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#define TARGET_LONG_BITS 64
|
||||
|
||||
#include "cpu-defs.h"
|
||||
|
||||
|
||||
#include <setjmp.h>
|
||||
|
||||
#include "softfloat.h"
|
||||
|
||||
/* XXX: put this in a common place */
|
||||
#define likely(x) __builtin_expect(!!(x), 1)
|
||||
#define unlikely(x) __builtin_expect(!!(x), 0)
|
||||
|
||||
#define TARGET_HAS_ICE 1
|
||||
|
||||
#define ELF_MACHINE EM_ALPHA
|
||||
|
||||
#define ICACHE_LINE_SIZE 32
|
||||
#define DCACHE_LINE_SIZE 32
|
||||
|
||||
#define TARGET_PAGE_BITS 12
|
||||
|
||||
#define VA_BITS 43
|
||||
|
||||
/* Alpha major type */
|
||||
enum {
|
||||
ALPHA_EV3 = 1,
|
||||
ALPHA_EV4 = 2,
|
||||
ALPHA_SIM = 3,
|
||||
ALPHA_LCA = 4,
|
||||
ALPHA_EV5 = 5, /* 21164 */
|
||||
ALPHA_EV45 = 6, /* 21064A */
|
||||
ALPHA_EV56 = 7, /* 21164A */
|
||||
};
|
||||
|
||||
/* EV4 minor type */
|
||||
enum {
|
||||
ALPHA_EV4_2 = 0,
|
||||
ALPHA_EV4_3 = 1,
|
||||
};
|
||||
|
||||
/* LCA minor type */
|
||||
enum {
|
||||
ALPHA_LCA_1 = 1, /* 21066 */
|
||||
ALPHA_LCA_2 = 2, /* 20166 */
|
||||
ALPHA_LCA_3 = 3, /* 21068 */
|
||||
ALPHA_LCA_4 = 4, /* 21068 */
|
||||
ALPHA_LCA_5 = 5, /* 21066A */
|
||||
ALPHA_LCA_6 = 6, /* 21068A */
|
||||
};
|
||||
|
||||
/* EV5 minor type */
|
||||
enum {
|
||||
ALPHA_EV5_1 = 1, /* Rev BA, CA */
|
||||
ALPHA_EV5_2 = 2, /* Rev DA, EA */
|
||||
ALPHA_EV5_3 = 3, /* Pass 3 */
|
||||
ALPHA_EV5_4 = 4, /* Pass 3.2 */
|
||||
ALPHA_EV5_5 = 5, /* Pass 4 */
|
||||
};
|
||||
|
||||
/* EV45 minor type */
|
||||
enum {
|
||||
ALPHA_EV45_1 = 1, /* Pass 1 */
|
||||
ALPHA_EV45_2 = 2, /* Pass 1.1 */
|
||||
ALPHA_EV45_3 = 3, /* Pass 2 */
|
||||
};
|
||||
|
||||
/* EV56 minor type */
|
||||
enum {
|
||||
ALPHA_EV56_1 = 1, /* Pass 1 */
|
||||
ALPHA_EV56_2 = 2, /* Pass 2 */
|
||||
};
|
||||
|
||||
enum {
|
||||
IMPLVER_2106x = 0, /* EV4, EV45 & LCA45 */
|
||||
IMPLVER_21164 = 1, /* EV5, EV56 & PCA45 */
|
||||
IMPLVER_21264 = 2, /* EV6, EV67 & EV68x */
|
||||
IMPLVER_21364 = 3, /* EV7 & EV79 */
|
||||
};
|
||||
|
||||
enum {
|
||||
AMASK_BWX = 0x00000001,
|
||||
AMASK_FIX = 0x00000002,
|
||||
AMASK_CIX = 0x00000004,
|
||||
AMASK_MVI = 0x00000100,
|
||||
AMASK_TRAP = 0x00000200,
|
||||
AMASK_PREFETCH = 0x00001000,
|
||||
};
|
||||
|
||||
enum {
|
||||
VAX_ROUND_NORMAL = 0,
|
||||
VAX_ROUND_CHOPPED,
|
||||
};
|
||||
|
||||
enum {
|
||||
IEEE_ROUND_NORMAL = 0,
|
||||
IEEE_ROUND_DYNAMIC,
|
||||
IEEE_ROUND_PLUS,
|
||||
IEEE_ROUND_MINUS,
|
||||
IEEE_ROUND_CHOPPED,
|
||||
};
|
||||
|
||||
/* IEEE floating-point operations encoding */
|
||||
/* Trap mode */
|
||||
enum {
|
||||
FP_TRAP_I = 0x0,
|
||||
FP_TRAP_U = 0x1,
|
||||
FP_TRAP_S = 0x4,
|
||||
FP_TRAP_SU = 0x5,
|
||||
FP_TRAP_SUI = 0x7,
|
||||
};
|
||||
|
||||
/* Rounding mode */
|
||||
enum {
|
||||
FP_ROUND_CHOPPED = 0x0,
|
||||
FP_ROUND_MINUS = 0x1,
|
||||
FP_ROUND_NORMAL = 0x2,
|
||||
FP_ROUND_DYNAMIC = 0x3,
|
||||
};
|
||||
|
||||
/* Internal processor registers */
|
||||
/* XXX: TOFIX: most of those registers are implementation dependant */
|
||||
enum {
|
||||
/* Ebox IPRs */
|
||||
IPR_CC = 0xC0,
|
||||
IPR_CC_CTL = 0xC1,
|
||||
IPR_VA = 0xC2,
|
||||
IPR_VA_CTL = 0xC4,
|
||||
IPR_VA_FORM = 0xC3,
|
||||
/* Ibox IPRs */
|
||||
IPR_ITB_TAG = 0x00,
|
||||
IPR_ITB_PTE = 0x01,
|
||||
IPT_ITB_IAP = 0x02,
|
||||
IPT_ITB_IA = 0x03,
|
||||
IPT_ITB_IS = 0x04,
|
||||
IPR_PMPC = 0x05,
|
||||
IPR_EXC_ADDR = 0x06,
|
||||
IPR_IVA_FORM = 0x07,
|
||||
IPR_CM = 0x09,
|
||||
IPR_IER = 0x0A,
|
||||
IPR_SIRR = 0x0C,
|
||||
IPR_ISUM = 0x0D,
|
||||
IPR_HW_INT_CLR = 0x0E,
|
||||
IPR_EXC_SUM = 0x0F,
|
||||
IPR_PAL_BASE = 0x10,
|
||||
IPR_I_CTL = 0x11,
|
||||
IPR_I_STAT = 0x16,
|
||||
IPR_IC_FLUSH = 0x13,
|
||||
IPR_IC_FLUSH_ASM = 0x12,
|
||||
IPR_CLR_MAP = 0x15,
|
||||
IPR_SLEEP = 0x17,
|
||||
IPR_PCTX = 0x40,
|
||||
IPR_PCTR_CTL = 0x14,
|
||||
/* Mbox IPRs */
|
||||
IPR_DTB_TAG0 = 0x20,
|
||||
IPR_DTB_TAG1 = 0xA0,
|
||||
IPR_DTB_PTE0 = 0x21,
|
||||
IPR_DTB_PTE1 = 0xA1,
|
||||
IPR_DTB_ALTMODE = 0xA6,
|
||||
IPR_DTB_IAP = 0xA2,
|
||||
IPR_DTB_IA = 0xA3,
|
||||
IPR_DTB_IS0 = 0x24,
|
||||
IPR_DTB_IS1 = 0xA4,
|
||||
IPR_DTB_ASN0 = 0x25,
|
||||
IPR_DTB_ASN1 = 0xA5,
|
||||
IPR_MM_STAT = 0x27,
|
||||
IPR_M_CTL = 0x28,
|
||||
IPR_DC_CTL = 0x29,
|
||||
IPR_DC_STAT = 0x2A,
|
||||
/* Cbox IPRs */
|
||||
IPR_C_DATA = 0x2B,
|
||||
IPR_C_SHIFT = 0x2C,
|
||||
|
||||
IPR_ASN,
|
||||
IPR_ASTEN,
|
||||
IPR_ASTSR,
|
||||
IPR_DATFX,
|
||||
IPR_ESP,
|
||||
IPR_FEN,
|
||||
IPR_IPIR,
|
||||
IPR_IPL,
|
||||
IPR_KSP,
|
||||
IPR_MCES,
|
||||
IPR_PERFMON,
|
||||
IPR_PCBB,
|
||||
IPR_PRBR,
|
||||
IPR_PTBR,
|
||||
IPR_SCBB,
|
||||
IPR_SISR,
|
||||
IPR_SSP,
|
||||
IPR_SYSPTBR,
|
||||
IPR_TBCHK,
|
||||
IPR_TBIA,
|
||||
IPR_TBIAP,
|
||||
IPR_TBIS,
|
||||
IPR_TBISD,
|
||||
IPR_TBISI,
|
||||
IPR_USP,
|
||||
IPR_VIRBND,
|
||||
IPR_VPTB,
|
||||
IPR_WHAMI,
|
||||
IPR_ALT_MODE,
|
||||
IPR_LAST,
|
||||
};
|
||||
|
||||
typedef struct CPUAlphaState CPUAlphaState;
|
||||
|
||||
typedef struct pal_handler_t pal_handler_t;
|
||||
struct pal_handler_t {
|
||||
/* Reset */
|
||||
void (*reset)(CPUAlphaState *env);
|
||||
/* Uncorrectable hardware error */
|
||||
void (*machine_check)(CPUAlphaState *env);
|
||||
/* Arithmetic exception */
|
||||
void (*arithmetic)(CPUAlphaState *env);
|
||||
/* Interrupt / correctable hardware error */
|
||||
void (*interrupt)(CPUAlphaState *env);
|
||||
/* Data fault */
|
||||
void (*dfault)(CPUAlphaState *env);
|
||||
/* DTB miss pal */
|
||||
void (*dtb_miss_pal)(CPUAlphaState *env);
|
||||
/* DTB miss native */
|
||||
void (*dtb_miss_native)(CPUAlphaState *env);
|
||||
/* Unaligned access */
|
||||
void (*unalign)(CPUAlphaState *env);
|
||||
/* ITB miss */
|
||||
void (*itb_miss)(CPUAlphaState *env);
|
||||
/* Instruction stream access violation */
|
||||
void (*itb_acv)(CPUAlphaState *env);
|
||||
/* Reserved or privileged opcode */
|
||||
void (*opcdec)(CPUAlphaState *env);
|
||||
/* Floating point exception */
|
||||
void (*fen)(CPUAlphaState *env);
|
||||
/* Call pal instruction */
|
||||
void (*call_pal)(CPUAlphaState *env, uint32_t palcode);
|
||||
};
|
||||
|
||||
struct CPUAlphaState {
|
||||
uint64_t ir[31];
|
||||
float64 fir[31];
|
||||
float_status fp_status;
|
||||
uint64_t fpcr;
|
||||
uint64_t pc;
|
||||
uint64_t lock;
|
||||
uint32_t pcc[2];
|
||||
uint64_t ipr[IPR_LAST];
|
||||
uint64_t ps;
|
||||
uint64_t unique;
|
||||
int saved_mode; /* Used for HW_LD / HW_ST */
|
||||
|
||||
/* */
|
||||
double ft0, ft1, ft2;
|
||||
|
||||
/* Those resources are used only in Qemu core */
|
||||
CPU_COMMON
|
||||
|
||||
jmp_buf jmp_env;
|
||||
int user_mode_only; /* user mode only simulation */
|
||||
uint32_t hflags;
|
||||
int halted;
|
||||
|
||||
int exception_index;
|
||||
int error_code;
|
||||
int interrupt_request;
|
||||
|
||||
uint32_t features;
|
||||
uint32_t amask;
|
||||
int implver;
|
||||
pal_handler_t *pal_handler;
|
||||
};
|
||||
|
||||
#include "cpu-all.h"
|
||||
|
||||
enum {
|
||||
FEATURE_ASN = 0x00000001,
|
||||
FEATURE_SPS = 0x00000002,
|
||||
FEATURE_VIRBND = 0x00000004,
|
||||
FEATURE_TBCHK = 0x00000008,
|
||||
};
|
||||
|
||||
enum {
|
||||
EXCP_RESET = 0x0000,
|
||||
EXCP_MCHK = 0x0020,
|
||||
EXCP_ARITH = 0x0060,
|
||||
EXCP_HW_INTERRUPT = 0x00E0,
|
||||
EXCP_DFAULT = 0x01E0,
|
||||
EXCP_DTB_MISS_PAL = 0x09E0,
|
||||
EXCP_ITB_MISS = 0x03E0,
|
||||
EXCP_ITB_ACV = 0x07E0,
|
||||
EXCP_DTB_MISS_NATIVE = 0x08E0,
|
||||
EXCP_UNALIGN = 0x11E0,
|
||||
EXCP_OPCDEC = 0x13E0,
|
||||
EXCP_FEN = 0x17E0,
|
||||
EXCP_CALL_PAL = 0x2000,
|
||||
EXCP_CALL_PALP = 0x3000,
|
||||
EXCP_CALL_PALE = 0x4000,
|
||||
/* Pseudo exception for console */
|
||||
EXCP_CONSOLE_DISPATCH = 0x4001,
|
||||
EXCP_CONSOLE_FIXUP = 0x4002,
|
||||
};
|
||||
|
||||
/* Arithmetic exception */
|
||||
enum {
|
||||
EXCP_ARITH_OVERFLOW,
|
||||
};
|
||||
|
||||
enum {
|
||||
PALCODE_CALL = 0x00000000,
|
||||
PALCODE_LD = 0x01000000,
|
||||
PALCODE_ST = 0x02000000,
|
||||
PALCODE_MFPR = 0x03000000,
|
||||
PALCODE_MTPR = 0x04000000,
|
||||
PALCODE_REI = 0x05000000,
|
||||
PALCODE_INIT = 0xF0000000,
|
||||
};
|
||||
|
||||
enum {
|
||||
IR_V0 = 0,
|
||||
IR_T0 = 1,
|
||||
IR_T1 = 2,
|
||||
IR_T2 = 3,
|
||||
IR_T3 = 4,
|
||||
IR_T4 = 5,
|
||||
IR_T5 = 6,
|
||||
IR_T6 = 7,
|
||||
IR_T7 = 8,
|
||||
IR_S0 = 9,
|
||||
IR_S1 = 10,
|
||||
IR_S2 = 11,
|
||||
IR_S3 = 12,
|
||||
IR_S4 = 13,
|
||||
IR_S5 = 14,
|
||||
IR_S6 = 15,
|
||||
#define IR_FP IR_S6
|
||||
IR_A0 = 16,
|
||||
IR_A1 = 17,
|
||||
IR_A2 = 18,
|
||||
IR_A3 = 19,
|
||||
IR_A4 = 20,
|
||||
IR_A5 = 21,
|
||||
IR_T8 = 22,
|
||||
IR_T9 = 23,
|
||||
IR_T10 = 24,
|
||||
IR_T11 = 25,
|
||||
IR_RA = 26,
|
||||
IR_T12 = 27,
|
||||
#define IR_PV IR_T12
|
||||
IR_AT = 28,
|
||||
IR_GP = 29,
|
||||
IR_SP = 30,
|
||||
IR_ZERO = 31,
|
||||
};
|
||||
|
||||
int cpu_alpha_mfpr (CPUState *env, int iprn, uint64_t *valp);
|
||||
int cpu_alpha_mtpr (CPUState *env, int iprn, uint64_t val, uint64_t *oldvalp);
|
||||
void cpu_loop_exit (void);
|
||||
void pal_init (CPUState *env);
|
||||
void call_pal (CPUState *env, int palcode);
|
||||
|
||||
#endif /* !defined (__CPU_ALPHA_H__) */
|
82
target-alpha/exec.h
Normal file
82
target-alpha/exec.h
Normal file
@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Alpha emulation cpu run-time definitions for qemu.
|
||||
*
|
||||
* Copyright (c) 2007 Jocelyn Mayer
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#if !defined (__ALPHA_EXEC_H__)
|
||||
#define __ALPHA_EXEC_H__
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "dyngen-exec.h"
|
||||
|
||||
#define TARGET_LONG_BITS 64
|
||||
|
||||
register struct CPUAlphaState *env asm(AREG0);
|
||||
|
||||
#if TARGET_LONG_BITS > HOST_LONG_BITS
|
||||
|
||||
/* no registers can be used */
|
||||
#define T0 (env->t0)
|
||||
#define T1 (env->t1)
|
||||
#define T2 (env->t2)
|
||||
|
||||
#else
|
||||
|
||||
register uint64_t T0 asm(AREG1);
|
||||
register uint64_t T1 asm(AREG2);
|
||||
register uint64_t T2 asm(AREG3);
|
||||
|
||||
#endif /* TARGET_LONG_BITS > HOST_LONG_BITS */
|
||||
|
||||
#define PARAM(n) ((uint64_t)PARAM##n)
|
||||
#define SPARAM(n) ((int32_t)PARAM##n)
|
||||
#define FT0 (env->ft0)
|
||||
#define FT1 (env->ft1)
|
||||
#define FT2 (env->ft2)
|
||||
#define FP_STATUS (env->fp_status)
|
||||
|
||||
#if defined (DEBUG_OP)
|
||||
#define RETURN() __asm__ __volatile__("nop" : : : "memory");
|
||||
#else
|
||||
#define RETURN() __asm__ __volatile__("" : : : "memory");
|
||||
#endif
|
||||
|
||||
#include "cpu.h"
|
||||
#include "exec-all.h"
|
||||
|
||||
#if !defined(CONFIG_USER_ONLY)
|
||||
#include "softmmu_exec.h"
|
||||
#endif /* !defined(CONFIG_USER_ONLY) */
|
||||
|
||||
static inline void env_to_regs(void)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void regs_to_env(void)
|
||||
{
|
||||
}
|
||||
|
||||
int cpu_alpha_handle_mmu_fault (CPUState *env, uint64_t address, int rw,
|
||||
int is_user, int is_softmmu);
|
||||
int cpu_alpha_mfpr (CPUState *env, int iprn, uint64_t *valp);
|
||||
int cpu_alpha_mtpr (CPUState *env, int iprn, uint64_t val, uint64_t *oldvalp);
|
||||
|
||||
void do_interrupt (CPUState *env);
|
||||
|
||||
#endif /* !defined (__ALPHA_EXEC_H__) */
|
454
target-alpha/helper.c
Normal file
454
target-alpha/helper.c
Normal file
@ -0,0 +1,454 @@
|
||||
/*
|
||||
* Alpha emulation cpu helpers for qemu.
|
||||
*
|
||||
* Copyright (c) 2007 Jocelyn Mayer
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "cpu.h"
|
||||
#include "exec-all.h"
|
||||
|
||||
#if defined(CONFIG_USER_ONLY)
|
||||
|
||||
int cpu_alpha_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
|
||||
int is_user, int is_softmmu)
|
||||
{
|
||||
if (rw == 2)
|
||||
env->exception_index = EXCP_ITB_MISS;
|
||||
else
|
||||
env->exception_index = EXCP_DFAULT;
|
||||
env->ipr[IPR_EXC_ADDR] = address;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
target_ulong cpu_get_phys_page_debug (CPUState *env, target_ulong addr)
|
||||
{
|
||||
return addr;
|
||||
}
|
||||
|
||||
void do_interrupt (CPUState *env)
|
||||
{
|
||||
env->exception_index = -1;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
target_ulong cpu_get_phys_page_debug (CPUState *env, target_ulong addr)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int cpu_alpha_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
|
||||
int is_user, int is_softmmu)
|
||||
{
|
||||
uint32_t opc;
|
||||
|
||||
if (rw == 2) {
|
||||
/* Instruction translation buffer miss */
|
||||
env->exception_index = EXCP_ITB_MISS;
|
||||
} else {
|
||||
if (env->ipr[IPR_EXC_ADDR] & 1)
|
||||
env->exception_index = EXCP_DTB_MISS_PAL;
|
||||
else
|
||||
env->exception_index = EXCP_DTB_MISS_NATIVE;
|
||||
opc = (ldl_code(env->pc) >> 21) << 4;
|
||||
if (rw) {
|
||||
opc |= 0x9;
|
||||
} else {
|
||||
opc |= 0x4;
|
||||
}
|
||||
env->ipr[IPR_MM_STAT] = opc;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int cpu_alpha_mfpr (CPUState *env, int iprn, uint64_t *valp)
|
||||
{
|
||||
uint64_t hwpcb;
|
||||
int ret = 0;
|
||||
|
||||
hwpcb = env->ipr[IPR_PCBB];
|
||||
switch (iprn) {
|
||||
case IPR_ASN:
|
||||
if (env->features & FEATURE_ASN)
|
||||
*valp = env->ipr[IPR_ASN];
|
||||
else
|
||||
*valp = 0;
|
||||
break;
|
||||
case IPR_ASTEN:
|
||||
*valp = ((int64_t)(env->ipr[IPR_ASTEN] << 60)) >> 60;
|
||||
break;
|
||||
case IPR_ASTSR:
|
||||
*valp = ((int64_t)(env->ipr[IPR_ASTSR] << 60)) >> 60;
|
||||
break;
|
||||
case IPR_DATFX:
|
||||
/* Write only */
|
||||
ret = -1;
|
||||
break;
|
||||
case IPR_ESP:
|
||||
if (env->features & FEATURE_SPS)
|
||||
*valp = env->ipr[IPR_ESP];
|
||||
else
|
||||
*valp = ldq_raw(hwpcb + 8);
|
||||
break;
|
||||
case IPR_FEN:
|
||||
*valp = ((int64_t)(env->ipr[IPR_FEN] << 63)) >> 63;
|
||||
break;
|
||||
case IPR_IPIR:
|
||||
/* Write-only */
|
||||
ret = -1;
|
||||
break;
|
||||
case IPR_IPL:
|
||||
*valp = ((int64_t)(env->ipr[IPR_IPL] << 59)) >> 59;
|
||||
break;
|
||||
case IPR_KSP:
|
||||
if (!(env->ipr[IPR_EXC_ADDR] & 1)) {
|
||||
ret = -1;
|
||||
} else {
|
||||
if (env->features & FEATURE_SPS)
|
||||
*valp = env->ipr[IPR_KSP];
|
||||
else
|
||||
*valp = ldq_raw(hwpcb + 0);
|
||||
}
|
||||
break;
|
||||
case IPR_MCES:
|
||||
*valp = ((int64_t)(env->ipr[IPR_MCES] << 59)) >> 59;
|
||||
break;
|
||||
case IPR_PERFMON:
|
||||
/* Implementation specific */
|
||||
*valp = 0;
|
||||
break;
|
||||
case IPR_PCBB:
|
||||
*valp = ((int64_t)env->ipr[IPR_PCBB] << 16) >> 16;
|
||||
break;
|
||||
case IPR_PRBR:
|
||||
*valp = env->ipr[IPR_PRBR];
|
||||
break;
|
||||
case IPR_PTBR:
|
||||
*valp = env->ipr[IPR_PTBR];
|
||||
break;
|
||||
case IPR_SCBB:
|
||||
*valp = (int64_t)((int32_t)env->ipr[IPR_SCBB]);
|
||||
break;
|
||||
case IPR_SIRR:
|
||||
/* Write-only */
|
||||
ret = -1;
|
||||
break;
|
||||
case IPR_SISR:
|
||||
*valp = (int64_t)((int16_t)env->ipr[IPR_SISR]);
|
||||
case IPR_SSP:
|
||||
if (env->features & FEATURE_SPS)
|
||||
*valp = env->ipr[IPR_SSP];
|
||||
else
|
||||
*valp = ldq_raw(hwpcb + 16);
|
||||
break;
|
||||
case IPR_SYSPTBR:
|
||||
if (env->features & FEATURE_VIRBND)
|
||||
*valp = env->ipr[IPR_SYSPTBR];
|
||||
else
|
||||
ret = -1;
|
||||
break;
|
||||
case IPR_TBCHK:
|
||||
if ((env->features & FEATURE_TBCHK)) {
|
||||
/* XXX: TODO */
|
||||
*valp = 0;
|
||||
ret = -1;
|
||||
} else {
|
||||
ret = -1;
|
||||
}
|
||||
break;
|
||||
case IPR_TBIA:
|
||||
/* Write-only */
|
||||
ret = -1;
|
||||
break;
|
||||
case IPR_TBIAP:
|
||||
/* Write-only */
|
||||
ret = -1;
|
||||
break;
|
||||
case IPR_TBIS:
|
||||
/* Write-only */
|
||||
ret = -1;
|
||||
break;
|
||||
case IPR_TBISD:
|
||||
/* Write-only */
|
||||
ret = -1;
|
||||
break;
|
||||
case IPR_TBISI:
|
||||
/* Write-only */
|
||||
ret = -1;
|
||||
break;
|
||||
case IPR_USP:
|
||||
if (env->features & FEATURE_SPS)
|
||||
*valp = env->ipr[IPR_USP];
|
||||
else
|
||||
*valp = ldq_raw(hwpcb + 24);
|
||||
break;
|
||||
case IPR_VIRBND:
|
||||
if (env->features & FEATURE_VIRBND)
|
||||
*valp = env->ipr[IPR_VIRBND];
|
||||
else
|
||||
ret = -1;
|
||||
break;
|
||||
case IPR_VPTB:
|
||||
*valp = env->ipr[IPR_VPTB];
|
||||
break;
|
||||
case IPR_WHAMI:
|
||||
*valp = env->ipr[IPR_WHAMI];
|
||||
break;
|
||||
default:
|
||||
/* Invalid */
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int cpu_alpha_mtpr (CPUState *env, int iprn, uint64_t val, uint64_t *oldvalp)
|
||||
{
|
||||
uint64_t hwpcb, tmp64;
|
||||
uint8_t tmp8;
|
||||
int ret = 0;
|
||||
|
||||
hwpcb = env->ipr[IPR_PCBB];
|
||||
switch (iprn) {
|
||||
case IPR_ASN:
|
||||
/* Read-only */
|
||||
ret = -1;
|
||||
break;
|
||||
case IPR_ASTEN:
|
||||
tmp8 = ((int8_t)(env->ipr[IPR_ASTEN] << 4)) >> 4;
|
||||
*oldvalp = tmp8;
|
||||
tmp8 &= val & 0xF;
|
||||
tmp8 |= (val >> 4) & 0xF;
|
||||
env->ipr[IPR_ASTEN] &= ~0xF;
|
||||
env->ipr[IPR_ASTEN] |= tmp8;
|
||||
ret = 1;
|
||||
break;
|
||||
case IPR_ASTSR:
|
||||
tmp8 = ((int8_t)(env->ipr[IPR_ASTSR] << 4)) >> 4;
|
||||
*oldvalp = tmp8;
|
||||
tmp8 &= val & 0xF;
|
||||
tmp8 |= (val >> 4) & 0xF;
|
||||
env->ipr[IPR_ASTSR] &= ~0xF;
|
||||
env->ipr[IPR_ASTSR] |= tmp8;
|
||||
ret = 1;
|
||||
case IPR_DATFX:
|
||||
env->ipr[IPR_DATFX] &= ~0x1;
|
||||
env->ipr[IPR_DATFX] |= val & 1;
|
||||
tmp64 = ldq_raw(hwpcb + 56);
|
||||
tmp64 &= ~0x8000000000000000ULL;
|
||||
tmp64 |= (val & 1) << 63;
|
||||
stq_raw(hwpcb + 56, tmp64);
|
||||
break;
|
||||
case IPR_ESP:
|
||||
if (env->features & FEATURE_SPS)
|
||||
env->ipr[IPR_ESP] = val;
|
||||
else
|
||||
stq_raw(hwpcb + 8, val);
|
||||
break;
|
||||
case IPR_FEN:
|
||||
env->ipr[IPR_FEN] = val & 1;
|
||||
tmp64 = ldq_raw(hwpcb + 56);
|
||||
tmp64 &= ~1;
|
||||
tmp64 |= val & 1;
|
||||
stq_raw(hwpcb + 56, tmp64);
|
||||
break;
|
||||
case IPR_IPIR:
|
||||
/* XXX: TODO: Send IRQ to CPU #ir[16] */
|
||||
break;
|
||||
case IPR_IPL:
|
||||
*oldvalp = ((int64_t)(env->ipr[IPR_IPL] << 59)) >> 59;
|
||||
env->ipr[IPR_IPL] &= ~0x1F;
|
||||
env->ipr[IPR_IPL] |= val & 0x1F;
|
||||
/* XXX: may issue an interrupt or ASR _now_ */
|
||||
ret = 1;
|
||||
break;
|
||||
case IPR_KSP:
|
||||
if (!(env->ipr[IPR_EXC_ADDR] & 1)) {
|
||||
ret = -1;
|
||||
} else {
|
||||
if (env->features & FEATURE_SPS)
|
||||
env->ipr[IPR_KSP] = val;
|
||||
else
|
||||
stq_raw(hwpcb + 0, val);
|
||||
}
|
||||
break;
|
||||
case IPR_MCES:
|
||||
env->ipr[IPR_MCES] &= ~((val & 0x7) | 0x18);
|
||||
env->ipr[IPR_MCES] |= val & 0x18;
|
||||
break;
|
||||
case IPR_PERFMON:
|
||||
/* Implementation specific */
|
||||
*oldvalp = 0;
|
||||
ret = 1;
|
||||
break;
|
||||
case IPR_PCBB:
|
||||
/* Read-only */
|
||||
ret = -1;
|
||||
break;
|
||||
case IPR_PRBR:
|
||||
env->ipr[IPR_PRBR] = val;
|
||||
break;
|
||||
case IPR_PTBR:
|
||||
/* Read-only */
|
||||
ret = -1;
|
||||
break;
|
||||
case IPR_SCBB:
|
||||
env->ipr[IPR_SCBB] = (uint32_t)val;
|
||||
break;
|
||||
case IPR_SIRR:
|
||||
if (val & 0xF) {
|
||||
env->ipr[IPR_SISR] |= 1 << (val & 0xF);
|
||||
/* XXX: request a software interrupt _now_ */
|
||||
}
|
||||
break;
|
||||
case IPR_SISR:
|
||||
/* Read-only */
|
||||
ret = -1;
|
||||
break;
|
||||
case IPR_SSP:
|
||||
if (env->features & FEATURE_SPS)
|
||||
env->ipr[IPR_SSP] = val;
|
||||
else
|
||||
stq_raw(hwpcb + 16, val);
|
||||
break;
|
||||
case IPR_SYSPTBR:
|
||||
if (env->features & FEATURE_VIRBND)
|
||||
env->ipr[IPR_SYSPTBR] = val;
|
||||
else
|
||||
ret = -1;
|
||||
case IPR_TBCHK:
|
||||
/* Read-only */
|
||||
ret = -1;
|
||||
break;
|
||||
case IPR_TBIA:
|
||||
tlb_flush(env, 1);
|
||||
break;
|
||||
case IPR_TBIAP:
|
||||
tlb_flush(env, 1);
|
||||
break;
|
||||
case IPR_TBIS:
|
||||
tlb_flush_page(env, val);
|
||||
break;
|
||||
case IPR_TBISD:
|
||||
tlb_flush_page(env, val);
|
||||
break;
|
||||
case IPR_TBISI:
|
||||
tlb_flush_page(env, val);
|
||||
break;
|
||||
case IPR_USP:
|
||||
if (env->features & FEATURE_SPS)
|
||||
env->ipr[IPR_USP] = val;
|
||||
else
|
||||
stq_raw(hwpcb + 24, val);
|
||||
break;
|
||||
case IPR_VIRBND:
|
||||
if (env->features & FEATURE_VIRBND)
|
||||
env->ipr[IPR_VIRBND] = val;
|
||||
else
|
||||
ret = -1;
|
||||
break;
|
||||
case IPR_VPTB:
|
||||
env->ipr[IPR_VPTB] = val;
|
||||
break;
|
||||
case IPR_WHAMI:
|
||||
/* Read-only */
|
||||
ret = -1;
|
||||
break;
|
||||
default:
|
||||
/* Invalid */
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void do_interrupt (CPUState *env)
|
||||
{
|
||||
int excp;
|
||||
|
||||
env->ipr[IPR_EXC_ADDR] = env->pc | 1;
|
||||
excp = env->exception_index;
|
||||
env->exception_index = 0;
|
||||
env->error_code = 0;
|
||||
/* XXX: disable interrupts and memory mapping */
|
||||
if (env->ipr[IPR_PAL_BASE] != -1ULL) {
|
||||
/* We use native PALcode */
|
||||
env->pc = env->ipr[IPR_PAL_BASE] + excp;
|
||||
} else {
|
||||
/* We use emulated PALcode */
|
||||
call_pal(env);
|
||||
/* Emulate REI */
|
||||
env->pc = env->ipr[IPR_EXC_ADDR] & ~7;
|
||||
env->ipr[IPR_EXC_ADDR] = env->ipr[IPR_EXC_ADDR] & 1;
|
||||
/* XXX: re-enable interrupts and memory mapping */
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void cpu_dump_state (CPUState *env, FILE *f,
|
||||
int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
|
||||
int flags)
|
||||
{
|
||||
static unsigned char *linux_reg_names[] = {
|
||||
"v0 ", "t0 ", "t1 ", "t2 ", "t3 ", "t4 ", "t5 ", "t6 ",
|
||||
"t7 ", "s0 ", "s1 ", "s2 ", "s3 ", "s4 ", "s5 ", "fp ",
|
||||
"a0 ", "a1 ", "a2 ", "a3 ", "a4 ", "a5 ", "t8 ", "t9 ",
|
||||
"t10", "t11", "ra ", "t12", "at ", "gp ", "sp ", "zero",
|
||||
};
|
||||
int i;
|
||||
|
||||
cpu_fprintf(f, " PC " TARGET_FMT_lx " PS " TARGET_FMT_lx "\n",
|
||||
env->pc, env->ps);
|
||||
for (i = 0; i < 31; i++) {
|
||||
cpu_fprintf(f, "IR%02d %s " TARGET_FMT_lx " ", i,
|
||||
linux_reg_names[i], env->ir[i]);
|
||||
if ((i % 3) == 2)
|
||||
cpu_fprintf(f, "\n");
|
||||
}
|
||||
cpu_fprintf(f, "\n");
|
||||
for (i = 0; i < 31; i++) {
|
||||
cpu_fprintf(f, "FIR%02d " TARGET_FMT_lx " ", i,
|
||||
*((uint64_t *)(&env->fir[i])));
|
||||
if ((i % 3) == 2)
|
||||
cpu_fprintf(f, "\n");
|
||||
}
|
||||
cpu_fprintf(f, "FT " TARGET_FMT_lx " " TARGET_FMT_lx " " TARGET_FMT_lx,
|
||||
*((uint64_t *)(&env->ft0)), *((uint64_t *)(&env->ft1)),
|
||||
*((uint64_t *)(&env->ft2)));
|
||||
cpu_fprintf(f, "\nMEM " TARGET_FMT_lx " %d %d\n",
|
||||
ldq_raw(0x000000004007df60ULL),
|
||||
(uint8_t *)(&env->ft0), (uint8_t *)(&env->fir[0]));
|
||||
}
|
||||
|
||||
void cpu_dump_EA (target_ulong EA)
|
||||
{
|
||||
FILE *f;
|
||||
|
||||
if (logfile)
|
||||
f = logfile;
|
||||
else
|
||||
f = stdout;
|
||||
fprintf(f, "Memory access at address " TARGET_FMT_lx "\n", EA);
|
||||
}
|
1103
target-alpha/op.c
Normal file
1103
target-alpha/op.c
Normal file
File diff suppressed because it is too large
Load Diff
1255
target-alpha/op_helper.c
Normal file
1255
target-alpha/op_helper.c
Normal file
File diff suppressed because it is too large
Load Diff
141
target-alpha/op_helper.h
Normal file
141
target-alpha/op_helper.h
Normal file
@ -0,0 +1,141 @@
|
||||
/*
|
||||
* Alpha emulation cpu micro-operations helpers definitions for qemu.
|
||||
*
|
||||
* Copyright (c) 2007 Jocelyn Mayer
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
void helper_call_pal (uint32_t palcode);
|
||||
void helper_excp (uint32_t excp, uint32_t error);
|
||||
void helper_amask (void);
|
||||
void helper_load_pcc (void);
|
||||
void helper_load_implver (void);
|
||||
void helper_load_fpcr (void);
|
||||
void helper_store_fpcr (void);
|
||||
void helper_load_irf (void);
|
||||
void helper_set_irf (void);
|
||||
void helper_clear_irf (void);
|
||||
void helper_addqv (void);
|
||||
void helper_addlv (void);
|
||||
void helper_subqv (void);
|
||||
void helper_sublv (void);
|
||||
void helper_mullv (void);
|
||||
void helper_mulqv (void);
|
||||
void helper_umulh (void);
|
||||
void helper_ctpop (void);
|
||||
void helper_ctlz (void);
|
||||
void helper_cttz (void);
|
||||
void helper_mskbl (void);
|
||||
void helper_extbl (void);
|
||||
void helper_insbl (void);
|
||||
void helper_mskwl (void);
|
||||
void helper_extwl (void);
|
||||
void helper_inswl (void);
|
||||
void helper_mskll (void);
|
||||
void helper_extll (void);
|
||||
void helper_insll (void);
|
||||
void helper_zap (void);
|
||||
void helper_zapnot (void);
|
||||
void helper_mskql (void);
|
||||
void helper_extql (void);
|
||||
void helper_insql (void);
|
||||
void helper_mskwh (void);
|
||||
void helper_inswh (void);
|
||||
void helper_extwh (void);
|
||||
void helper_msklh (void);
|
||||
void helper_inslh (void);
|
||||
void helper_extlh (void);
|
||||
void helper_mskqh (void);
|
||||
void helper_insqh (void);
|
||||
void helper_extqh (void);
|
||||
void helper_cmpbge (void);
|
||||
void helper_cmov_fir (int freg);
|
||||
|
||||
double helper_ldff_raw (target_ulong ea);
|
||||
void helper_stff_raw (target_ulong ea, double op);
|
||||
double helper_ldfg_raw (target_ulong ea);
|
||||
void helper_stfg_raw (target_ulong ea, double op);
|
||||
#if !defined(CONFIG_USER_ONLY)
|
||||
double helper_ldff_user (target_ulong ea);
|
||||
void helper_stff_user (target_ulong ea, double op);
|
||||
double helper_ldff_kernel (target_ulong ea);
|
||||
void helper_stff_kernel (target_ulong ea, double op);
|
||||
double helper_ldff_data (target_ulong ea);
|
||||
void helper_stff_data (target_ulong ea, double op);
|
||||
double helper_ldfg_user (target_ulong ea);
|
||||
void helper_stfg_user (target_ulong ea, double op);
|
||||
double helper_ldfg_kernel (target_ulong ea);
|
||||
void helper_stfg_kernel (target_ulong ea, double op);
|
||||
double helper_ldfg_data (target_ulong ea);
|
||||
void helper_stfg_data (target_ulong ea, double op);
|
||||
#endif
|
||||
|
||||
void helper_sqrts (void);
|
||||
void helper_cpys (void);
|
||||
void helper_cpysn (void);
|
||||
void helper_cpyse (void);
|
||||
void helper_itofs (void);
|
||||
void helper_ftois (void);
|
||||
|
||||
void helper_sqrtt (void);
|
||||
void helper_cmptun (void);
|
||||
void helper_cmpteq (void);
|
||||
void helper_cmptle (void);
|
||||
void helper_cmptlt (void);
|
||||
void helper_itoft (void);
|
||||
void helper_ftoit (void);
|
||||
|
||||
void helper_addf (void);
|
||||
void helper_subf (void);
|
||||
void helper_mulf (void);
|
||||
void helper_divf (void);
|
||||
void helper_sqrtf (void);
|
||||
void helper_cmpfeq (void);
|
||||
void helper_cmpfne (void);
|
||||
void helper_cmpflt (void);
|
||||
void helper_cmpfle (void);
|
||||
void helper_cmpfgt (void);
|
||||
void helper_cmpfge (void);
|
||||
void helper_itoff (void);
|
||||
|
||||
void helper_addg (void);
|
||||
void helper_subg (void);
|
||||
void helper_mulg (void);
|
||||
void helper_divg (void);
|
||||
void helper_sqrtg (void);
|
||||
void helper_cmpgeq (void);
|
||||
void helper_cmpglt (void);
|
||||
void helper_cmpgle (void);
|
||||
|
||||
void helper_cvtqs (void);
|
||||
void helper_cvttq (void);
|
||||
void helper_cvtqt (void);
|
||||
void helper_cvtqf (void);
|
||||
void helper_cvtgf (void);
|
||||
void helper_cvtgd (void);
|
||||
void helper_cvtgq (void);
|
||||
void helper_cvtqg (void);
|
||||
void helper_cvtdg (void);
|
||||
void helper_cvtlq (void);
|
||||
void helper_cvtql (void);
|
||||
void helper_cvtqlv (void);
|
||||
void helper_cvtqlsv (void);
|
||||
|
||||
void helper_mfpr (int iprn);
|
||||
void helper_mtpr (int iprn);
|
||||
void helper_ld_phys_to_virt (void);
|
||||
void helper_st_phys_to_virt (void);
|
||||
void helper_tb_flush (void);
|
40
target-alpha/op_helper_mem.h
Normal file
40
target-alpha/op_helper_mem.h
Normal file
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Alpha emulation cpu micro-operations helpers for memory accesses for qemu.
|
||||
*
|
||||
* Copyright (c) 2007 Jocelyn Mayer
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* XXX: TODO */
|
||||
double glue(helper_ldff, MEMSUFFIX) (target_ulong ea)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void glue(helper_stff, MEMSUFFIX) (target_ulong ea, double op)
|
||||
{
|
||||
}
|
||||
|
||||
double glue(helper_ldfg, MEMSUFFIX) (target_ulong ea)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void glue(helper_stfg, MEMSUFFIX) (target_ulong ea, double op)
|
||||
{
|
||||
}
|
||||
|
||||
#undef MEMSUFFIX
|
125
target-alpha/op_mem.h
Normal file
125
target-alpha/op_mem.h
Normal file
@ -0,0 +1,125 @@
|
||||
/*
|
||||
* Alpha emulation cpu micro-operations for memory accesses for qemu.
|
||||
*
|
||||
* Copyright (c) 2007 Jocelyn Mayer
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#define DEBUG_MEM_ACCESSES
|
||||
#if defined (DEBUG_MEM_ACCESSES)
|
||||
void helper_print_mem_EA (target_ulong EA);
|
||||
#define print_mem_EA(EA) do { helper_print_mem_EA(EA); } while (0)
|
||||
#else
|
||||
#define print_mem_EA(EA) do { } while (0)
|
||||
#endif
|
||||
|
||||
static inline uint32_t glue(ldl_l, MEMSUFFIX) (target_ulong EA)
|
||||
{
|
||||
env->lock = EA;
|
||||
|
||||
return glue(ldl, MEMSUFFIX)(EA);
|
||||
}
|
||||
|
||||
static inline uint32_t glue(ldq_l, MEMSUFFIX) (target_ulong EA)
|
||||
{
|
||||
env->lock = EA;
|
||||
|
||||
return glue(ldq, MEMSUFFIX)(EA);
|
||||
}
|
||||
|
||||
static inline void glue(stl_c, MEMSUFFIX) (target_ulong EA, uint32_t data)
|
||||
{
|
||||
if (EA == env->lock) {
|
||||
glue(stl, MEMSUFFIX)(EA, data);
|
||||
T0 = 0;
|
||||
} else {
|
||||
T0 = 1;
|
||||
}
|
||||
env->lock = -1;
|
||||
}
|
||||
|
||||
static inline void glue(stq_c, MEMSUFFIX) (target_ulong EA, uint64_t data)
|
||||
{
|
||||
if (EA == env->lock) {
|
||||
glue(stq, MEMSUFFIX)(EA, data);
|
||||
T0 = 0;
|
||||
} else {
|
||||
T0 = 1;
|
||||
}
|
||||
env->lock = -1;
|
||||
}
|
||||
|
||||
#define ALPHA_LD_OP(name, op) \
|
||||
void OPPROTO glue(glue(op_ld, name), MEMSUFFIX) (void) \
|
||||
{ \
|
||||
print_mem_EA(T0); \
|
||||
T1 = glue(op, MEMSUFFIX)(T0); \
|
||||
RETURN(); \
|
||||
}
|
||||
|
||||
#define ALPHA_ST_OP(name, op) \
|
||||
void OPPROTO glue(glue(op_st, name), MEMSUFFIX) (void) \
|
||||
{ \
|
||||
print_mem_EA(T0); \
|
||||
glue(op, MEMSUFFIX)(T0, T1); \
|
||||
RETURN(); \
|
||||
}
|
||||
|
||||
ALPHA_LD_OP(bu, ldub);
|
||||
ALPHA_ST_OP(b, stb);
|
||||
ALPHA_LD_OP(wu, lduw);
|
||||
ALPHA_ST_OP(w, stw);
|
||||
ALPHA_LD_OP(l, ldl);
|
||||
ALPHA_ST_OP(l, stl);
|
||||
ALPHA_LD_OP(q, ldq);
|
||||
ALPHA_ST_OP(q, stq);
|
||||
|
||||
ALPHA_LD_OP(q_u, ldq);
|
||||
ALPHA_ST_OP(q_u, stq);
|
||||
|
||||
ALPHA_LD_OP(l_l, ldl_l);
|
||||
ALPHA_LD_OP(q_l, ldq_l);
|
||||
ALPHA_ST_OP(l_c, stl_c);
|
||||
ALPHA_ST_OP(q_c, stq_c);
|
||||
|
||||
#define ALPHA_LDF_OP(name, op) \
|
||||
void OPPROTO glue(glue(op_ld, name), MEMSUFFIX) (void) \
|
||||
{ \
|
||||
print_mem_EA(T0); \
|
||||
FT1 = glue(op, MEMSUFFIX)(T0); \
|
||||
RETURN(); \
|
||||
}
|
||||
|
||||
#define ALPHA_STF_OP(name, op) \
|
||||
void OPPROTO glue(glue(op_st, name), MEMSUFFIX) (void) \
|
||||
{ \
|
||||
print_mem_EA(T0); \
|
||||
glue(op, MEMSUFFIX)(T0, FT1); \
|
||||
RETURN(); \
|
||||
}
|
||||
|
||||
ALPHA_LDF_OP(t, ldfq);
|
||||
ALPHA_STF_OP(t, stfq);
|
||||
ALPHA_LDF_OP(s, ldfl);
|
||||
ALPHA_STF_OP(s, stfl);
|
||||
|
||||
/* VAX floating point */
|
||||
ALPHA_LDF_OP(f, helper_ldff);
|
||||
ALPHA_STF_OP(f, helper_stff);
|
||||
ALPHA_LDF_OP(g, helper_ldfg);
|
||||
ALPHA_STF_OP(g, helper_stfg);
|
||||
|
||||
#undef MEMSUFFIX
|
167
target-alpha/op_template.h
Normal file
167
target-alpha/op_template.h
Normal file
@ -0,0 +1,167 @@
|
||||
/*
|
||||
* Alpha emulation cpu micro-operations templates for qemu.
|
||||
*
|
||||
* Copyright (c) 2007 Jocelyn Mayer
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* Optimized constant loads */
|
||||
#if REG < 3
|
||||
void OPPROTO glue(op_reset_T, REG) (void)
|
||||
{
|
||||
glue(T, REG) = 0;
|
||||
RETURN();
|
||||
}
|
||||
|
||||
void OPPROTO glue(op_reset_FT, REG) (void)
|
||||
{
|
||||
glue(FT, REG) = 0;
|
||||
RETURN();
|
||||
}
|
||||
|
||||
/* XXX: This can be great on most RISC machines */
|
||||
#if !defined(__i386__) && !defined(__x86_64__)
|
||||
void OPPROTO glue(op_set_s16_T, REG) (void)
|
||||
{
|
||||
glue(T, REG) = (int16_t)PARAM(1);
|
||||
RETURN();
|
||||
}
|
||||
|
||||
void OPPROTO glue(op_set_u16_T, REG) (void)
|
||||
{
|
||||
glue(T, REG) = (uint16_t)PARAM(1);
|
||||
RETURN();
|
||||
}
|
||||
#endif
|
||||
|
||||
void OPPROTO glue(op_set_s32_T, REG) (void)
|
||||
{
|
||||
glue(T, REG) = (int32_t)PARAM(1);
|
||||
RETURN();
|
||||
}
|
||||
|
||||
void OPPROTO glue(op_set_u32_T, REG) (void)
|
||||
{
|
||||
glue(T, REG) = (uint32_t)PARAM(1);
|
||||
RETURN();
|
||||
}
|
||||
|
||||
#if 0 // Qemu does not know how to do this...
|
||||
void OPPROTO glue(op_set_64_T, REG) (void)
|
||||
{
|
||||
glue(T, REG) = (int64_t)PARAM(1);
|
||||
RETURN();
|
||||
}
|
||||
#else
|
||||
void OPPROTO glue(op_set_64_T, REG) (void)
|
||||
{
|
||||
glue(T, REG) = ((int64_t)PARAM(1) << 32) | (int64_t)PARAM(2);
|
||||
RETURN();
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* REG < 3 */
|
||||
|
||||
/* Fixed-point register moves */
|
||||
#if REG < 31
|
||||
void OPPROTO glue(op_load_T0_ir, REG) (void)
|
||||
{
|
||||
T0 = env->ir[REG];
|
||||
RETURN();
|
||||
}
|
||||
|
||||
void OPPROTO glue(op_load_T1_ir, REG) (void)
|
||||
{
|
||||
T1 = env->ir[REG];
|
||||
RETURN();
|
||||
}
|
||||
|
||||
void OPPROTO glue(op_load_T2_ir, REG) (void)
|
||||
{
|
||||
T2 = env->ir[REG];
|
||||
RETURN();
|
||||
}
|
||||
|
||||
void OPPROTO glue(op_store_T0_ir, REG) (void)
|
||||
{
|
||||
env->ir[REG] = T0;
|
||||
RETURN();
|
||||
}
|
||||
|
||||
void OPPROTO glue(op_store_T1_ir, REG) (void)
|
||||
{
|
||||
env->ir[REG] = T1;
|
||||
RETURN();
|
||||
}
|
||||
|
||||
void OPPROTO glue(op_store_T2_ir, REG) (void)
|
||||
{
|
||||
env->ir[REG] = T2;
|
||||
RETURN();
|
||||
}
|
||||
|
||||
void OPPROTO glue(op_cmov_ir, REG) (void)
|
||||
{
|
||||
if (T0)
|
||||
env->ir[REG] = T1;
|
||||
RETURN();
|
||||
}
|
||||
|
||||
/* floating point registers moves */
|
||||
void OPPROTO glue(op_load_FT0_fir, REG) (void)
|
||||
{
|
||||
FT0 = env->fir[REG];
|
||||
RETURN();
|
||||
}
|
||||
|
||||
void OPPROTO glue(op_load_FT1_fir, REG) (void)
|
||||
{
|
||||
FT1 = env->fir[REG];
|
||||
RETURN();
|
||||
}
|
||||
|
||||
void OPPROTO glue(op_load_FT2_fir, REG) (void)
|
||||
{
|
||||
FT2 = env->fir[REG];
|
||||
RETURN();
|
||||
}
|
||||
|
||||
void OPPROTO glue(op_store_FT0_fir, REG) (void)
|
||||
{
|
||||
env->fir[REG] = FT0;
|
||||
RETURN();
|
||||
}
|
||||
|
||||
void OPPROTO glue(op_store_FT1_fir, REG) (void)
|
||||
{
|
||||
env->fir[REG] = FT1;
|
||||
RETURN();
|
||||
}
|
||||
|
||||
void OPPROTO glue(op_store_FT2_fir, REG) (void)
|
||||
{
|
||||
env->fir[REG] = FT2;
|
||||
RETURN();
|
||||
}
|
||||
|
||||
void OPPROTO glue(op_cmov_fir, REG) (void)
|
||||
{
|
||||
helper_cmov_fir(REG);
|
||||
RETURN();
|
||||
}
|
||||
#endif /* REG < 31 */
|
||||
|
||||
#undef REG
|
2117
target-alpha/translate.c
Normal file
2117
target-alpha/translate.c
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user