Commit 4c9649a967e45bc3086d2e752871878e08d6cdf2

Authored by j_mayer
1 parent 6fa4cea9

Alpha architecture emulation core.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2597 c046a42c-6fe2-441c-8c8c-71466251a162

Too many changes to show.

To preserve performance only 9 of 10 files are displayed.

target-alpha/cpu.h 0 → 100644
  1 +/*
  2 + * Alpha emulation cpu definitions for qemu.
  3 + *
  4 + * Copyright (c) 2007 Jocelyn Mayer
  5 + *
  6 + * This library is free software; you can redistribute it and/or
  7 + * modify it under the terms of the GNU Lesser General Public
  8 + * License as published by the Free Software Foundation; either
  9 + * version 2 of the License, or (at your option) any later version.
  10 + *
  11 + * This library is distributed in the hope that it will be useful,
  12 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14 + * Lesser General Public License for more details.
  15 + *
  16 + * You should have received a copy of the GNU Lesser General Public
  17 + * License along with this library; if not, write to the Free Software
  18 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  19 + */
  20 +
  21 +#if !defined (__CPU_ALPHA_H__)
  22 +#define __CPU_ALPHA_H__
  23 +
  24 +#include "config.h"
  25 +
  26 +#define TARGET_LONG_BITS 64
  27 +
  28 +#include "cpu-defs.h"
  29 +
  30 +
  31 +#include <setjmp.h>
  32 +
  33 +#include "softfloat.h"
  34 +
  35 +/* XXX: put this in a common place */
  36 +#define likely(x) __builtin_expect(!!(x), 1)
  37 +#define unlikely(x) __builtin_expect(!!(x), 0)
  38 +
  39 +#define TARGET_HAS_ICE 1
  40 +
  41 +#define ELF_MACHINE EM_ALPHA
  42 +
  43 +#define ICACHE_LINE_SIZE 32
  44 +#define DCACHE_LINE_SIZE 32
  45 +
  46 +#define TARGET_PAGE_BITS 12
  47 +
  48 +#define VA_BITS 43
  49 +
  50 +/* Alpha major type */
  51 +enum {
  52 + ALPHA_EV3 = 1,
  53 + ALPHA_EV4 = 2,
  54 + ALPHA_SIM = 3,
  55 + ALPHA_LCA = 4,
  56 + ALPHA_EV5 = 5, /* 21164 */
  57 + ALPHA_EV45 = 6, /* 21064A */
  58 + ALPHA_EV56 = 7, /* 21164A */
  59 +};
  60 +
  61 +/* EV4 minor type */
  62 +enum {
  63 + ALPHA_EV4_2 = 0,
  64 + ALPHA_EV4_3 = 1,
  65 +};
  66 +
  67 +/* LCA minor type */
  68 +enum {
  69 + ALPHA_LCA_1 = 1, /* 21066 */
  70 + ALPHA_LCA_2 = 2, /* 20166 */
  71 + ALPHA_LCA_3 = 3, /* 21068 */
  72 + ALPHA_LCA_4 = 4, /* 21068 */
  73 + ALPHA_LCA_5 = 5, /* 21066A */
  74 + ALPHA_LCA_6 = 6, /* 21068A */
  75 +};
  76 +
  77 +/* EV5 minor type */
  78 +enum {
  79 + ALPHA_EV5_1 = 1, /* Rev BA, CA */
  80 + ALPHA_EV5_2 = 2, /* Rev DA, EA */
  81 + ALPHA_EV5_3 = 3, /* Pass 3 */
  82 + ALPHA_EV5_4 = 4, /* Pass 3.2 */
  83 + ALPHA_EV5_5 = 5, /* Pass 4 */
  84 +};
  85 +
  86 +/* EV45 minor type */
  87 +enum {
  88 + ALPHA_EV45_1 = 1, /* Pass 1 */
  89 + ALPHA_EV45_2 = 2, /* Pass 1.1 */
  90 + ALPHA_EV45_3 = 3, /* Pass 2 */
  91 +};
  92 +
  93 +/* EV56 minor type */
  94 +enum {
  95 + ALPHA_EV56_1 = 1, /* Pass 1 */
  96 + ALPHA_EV56_2 = 2, /* Pass 2 */
  97 +};
  98 +
  99 +enum {
  100 + IMPLVER_2106x = 0, /* EV4, EV45 & LCA45 */
  101 + IMPLVER_21164 = 1, /* EV5, EV56 & PCA45 */
  102 + IMPLVER_21264 = 2, /* EV6, EV67 & EV68x */
  103 + IMPLVER_21364 = 3, /* EV7 & EV79 */
  104 +};
  105 +
  106 +enum {
  107 + AMASK_BWX = 0x00000001,
  108 + AMASK_FIX = 0x00000002,
  109 + AMASK_CIX = 0x00000004,
  110 + AMASK_MVI = 0x00000100,
  111 + AMASK_TRAP = 0x00000200,
  112 + AMASK_PREFETCH = 0x00001000,
  113 +};
  114 +
  115 +enum {
  116 + VAX_ROUND_NORMAL = 0,
  117 + VAX_ROUND_CHOPPED,
  118 +};
  119 +
  120 +enum {
  121 + IEEE_ROUND_NORMAL = 0,
  122 + IEEE_ROUND_DYNAMIC,
  123 + IEEE_ROUND_PLUS,
  124 + IEEE_ROUND_MINUS,
  125 + IEEE_ROUND_CHOPPED,
  126 +};
  127 +
  128 +/* IEEE floating-point operations encoding */
  129 +/* Trap mode */
  130 +enum {
  131 + FP_TRAP_I = 0x0,
  132 + FP_TRAP_U = 0x1,
  133 + FP_TRAP_S = 0x4,
  134 + FP_TRAP_SU = 0x5,
  135 + FP_TRAP_SUI = 0x7,
  136 +};
  137 +
  138 +/* Rounding mode */
  139 +enum {
  140 + FP_ROUND_CHOPPED = 0x0,
  141 + FP_ROUND_MINUS = 0x1,
  142 + FP_ROUND_NORMAL = 0x2,
  143 + FP_ROUND_DYNAMIC = 0x3,
  144 +};
  145 +
  146 +/* Internal processor registers */
  147 +/* XXX: TOFIX: most of those registers are implementation dependant */
  148 +enum {
  149 + /* Ebox IPRs */
  150 + IPR_CC = 0xC0,
  151 + IPR_CC_CTL = 0xC1,
  152 + IPR_VA = 0xC2,
  153 + IPR_VA_CTL = 0xC4,
  154 + IPR_VA_FORM = 0xC3,
  155 + /* Ibox IPRs */
  156 + IPR_ITB_TAG = 0x00,
  157 + IPR_ITB_PTE = 0x01,
  158 + IPT_ITB_IAP = 0x02,
  159 + IPT_ITB_IA = 0x03,
  160 + IPT_ITB_IS = 0x04,
  161 + IPR_PMPC = 0x05,
  162 + IPR_EXC_ADDR = 0x06,
  163 + IPR_IVA_FORM = 0x07,
  164 + IPR_CM = 0x09,
  165 + IPR_IER = 0x0A,
  166 + IPR_SIRR = 0x0C,
  167 + IPR_ISUM = 0x0D,
  168 + IPR_HW_INT_CLR = 0x0E,
  169 + IPR_EXC_SUM = 0x0F,
  170 + IPR_PAL_BASE = 0x10,
  171 + IPR_I_CTL = 0x11,
  172 + IPR_I_STAT = 0x16,
  173 + IPR_IC_FLUSH = 0x13,
  174 + IPR_IC_FLUSH_ASM = 0x12,
  175 + IPR_CLR_MAP = 0x15,
  176 + IPR_SLEEP = 0x17,
  177 + IPR_PCTX = 0x40,
  178 + IPR_PCTR_CTL = 0x14,
  179 + /* Mbox IPRs */
  180 + IPR_DTB_TAG0 = 0x20,
  181 + IPR_DTB_TAG1 = 0xA0,
  182 + IPR_DTB_PTE0 = 0x21,
  183 + IPR_DTB_PTE1 = 0xA1,
  184 + IPR_DTB_ALTMODE = 0xA6,
  185 + IPR_DTB_IAP = 0xA2,
  186 + IPR_DTB_IA = 0xA3,
  187 + IPR_DTB_IS0 = 0x24,
  188 + IPR_DTB_IS1 = 0xA4,
  189 + IPR_DTB_ASN0 = 0x25,
  190 + IPR_DTB_ASN1 = 0xA5,
  191 + IPR_MM_STAT = 0x27,
  192 + IPR_M_CTL = 0x28,
  193 + IPR_DC_CTL = 0x29,
  194 + IPR_DC_STAT = 0x2A,
  195 + /* Cbox IPRs */
  196 + IPR_C_DATA = 0x2B,
  197 + IPR_C_SHIFT = 0x2C,
  198 +
  199 + IPR_ASN,
  200 + IPR_ASTEN,
  201 + IPR_ASTSR,
  202 + IPR_DATFX,
  203 + IPR_ESP,
  204 + IPR_FEN,
  205 + IPR_IPIR,
  206 + IPR_IPL,
  207 + IPR_KSP,
  208 + IPR_MCES,
  209 + IPR_PERFMON,
  210 + IPR_PCBB,
  211 + IPR_PRBR,
  212 + IPR_PTBR,
  213 + IPR_SCBB,
  214 + IPR_SISR,
  215 + IPR_SSP,
  216 + IPR_SYSPTBR,
  217 + IPR_TBCHK,
  218 + IPR_TBIA,
  219 + IPR_TBIAP,
  220 + IPR_TBIS,
  221 + IPR_TBISD,
  222 + IPR_TBISI,
  223 + IPR_USP,
  224 + IPR_VIRBND,
  225 + IPR_VPTB,
  226 + IPR_WHAMI,
  227 + IPR_ALT_MODE,
  228 + IPR_LAST,
  229 +};
  230 +
  231 +typedef struct CPUAlphaState CPUAlphaState;
  232 +
  233 +typedef struct pal_handler_t pal_handler_t;
  234 +struct pal_handler_t {
  235 + /* Reset */
  236 + void (*reset)(CPUAlphaState *env);
  237 + /* Uncorrectable hardware error */
  238 + void (*machine_check)(CPUAlphaState *env);
  239 + /* Arithmetic exception */
  240 + void (*arithmetic)(CPUAlphaState *env);
  241 + /* Interrupt / correctable hardware error */
  242 + void (*interrupt)(CPUAlphaState *env);
  243 + /* Data fault */
  244 + void (*dfault)(CPUAlphaState *env);
  245 + /* DTB miss pal */
  246 + void (*dtb_miss_pal)(CPUAlphaState *env);
  247 + /* DTB miss native */
  248 + void (*dtb_miss_native)(CPUAlphaState *env);
  249 + /* Unaligned access */
  250 + void (*unalign)(CPUAlphaState *env);
  251 + /* ITB miss */
  252 + void (*itb_miss)(CPUAlphaState *env);
  253 + /* Instruction stream access violation */
  254 + void (*itb_acv)(CPUAlphaState *env);
  255 + /* Reserved or privileged opcode */
  256 + void (*opcdec)(CPUAlphaState *env);
  257 + /* Floating point exception */
  258 + void (*fen)(CPUAlphaState *env);
  259 + /* Call pal instruction */
  260 + void (*call_pal)(CPUAlphaState *env, uint32_t palcode);
  261 +};
  262 +
  263 +struct CPUAlphaState {
  264 + uint64_t ir[31];
  265 + float64 fir[31];
  266 + float_status fp_status;
  267 + uint64_t fpcr;
  268 + uint64_t pc;
  269 + uint64_t lock;
  270 + uint32_t pcc[2];
  271 + uint64_t ipr[IPR_LAST];
  272 + uint64_t ps;
  273 + uint64_t unique;
  274 + int saved_mode; /* Used for HW_LD / HW_ST */
  275 +
  276 + /* */
  277 + double ft0, ft1, ft2;
  278 +
  279 + /* Those resources are used only in Qemu core */
  280 + CPU_COMMON
  281 +
  282 + jmp_buf jmp_env;
  283 + int user_mode_only; /* user mode only simulation */
  284 + uint32_t hflags;
  285 + int halted;
  286 +
  287 + int exception_index;
  288 + int error_code;
  289 + int interrupt_request;
  290 +
  291 + uint32_t features;
  292 + uint32_t amask;
  293 + int implver;
  294 + pal_handler_t *pal_handler;
  295 +};
  296 +
  297 +#include "cpu-all.h"
  298 +
  299 +enum {
  300 + FEATURE_ASN = 0x00000001,
  301 + FEATURE_SPS = 0x00000002,
  302 + FEATURE_VIRBND = 0x00000004,
  303 + FEATURE_TBCHK = 0x00000008,
  304 +};
  305 +
  306 +enum {
  307 + EXCP_RESET = 0x0000,
  308 + EXCP_MCHK = 0x0020,
  309 + EXCP_ARITH = 0x0060,
  310 + EXCP_HW_INTERRUPT = 0x00E0,
  311 + EXCP_DFAULT = 0x01E0,
  312 + EXCP_DTB_MISS_PAL = 0x09E0,
  313 + EXCP_ITB_MISS = 0x03E0,
  314 + EXCP_ITB_ACV = 0x07E0,
  315 + EXCP_DTB_MISS_NATIVE = 0x08E0,
  316 + EXCP_UNALIGN = 0x11E0,
  317 + EXCP_OPCDEC = 0x13E0,
  318 + EXCP_FEN = 0x17E0,
  319 + EXCP_CALL_PAL = 0x2000,
  320 + EXCP_CALL_PALP = 0x3000,
  321 + EXCP_CALL_PALE = 0x4000,
  322 + /* Pseudo exception for console */
  323 + EXCP_CONSOLE_DISPATCH = 0x4001,
  324 + EXCP_CONSOLE_FIXUP = 0x4002,
  325 +};
  326 +
  327 +/* Arithmetic exception */
  328 +enum {
  329 + EXCP_ARITH_OVERFLOW,
  330 +};
  331 +
  332 +enum {
  333 + PALCODE_CALL = 0x00000000,
  334 + PALCODE_LD = 0x01000000,
  335 + PALCODE_ST = 0x02000000,
  336 + PALCODE_MFPR = 0x03000000,
  337 + PALCODE_MTPR = 0x04000000,
  338 + PALCODE_REI = 0x05000000,
  339 + PALCODE_INIT = 0xF0000000,
  340 +};
  341 +
  342 +enum {
  343 + IR_V0 = 0,
  344 + IR_T0 = 1,
  345 + IR_T1 = 2,
  346 + IR_T2 = 3,
  347 + IR_T3 = 4,
  348 + IR_T4 = 5,
  349 + IR_T5 = 6,
  350 + IR_T6 = 7,
  351 + IR_T7 = 8,
  352 + IR_S0 = 9,
  353 + IR_S1 = 10,
  354 + IR_S2 = 11,
  355 + IR_S3 = 12,
  356 + IR_S4 = 13,
  357 + IR_S5 = 14,
  358 + IR_S6 = 15,
  359 +#define IR_FP IR_S6
  360 + IR_A0 = 16,
  361 + IR_A1 = 17,
  362 + IR_A2 = 18,
  363 + IR_A3 = 19,
  364 + IR_A4 = 20,
  365 + IR_A5 = 21,
  366 + IR_T8 = 22,
  367 + IR_T9 = 23,
  368 + IR_T10 = 24,
  369 + IR_T11 = 25,
  370 + IR_RA = 26,
  371 + IR_T12 = 27,
  372 +#define IR_PV IR_T12
  373 + IR_AT = 28,
  374 + IR_GP = 29,
  375 + IR_SP = 30,
  376 + IR_ZERO = 31,
  377 +};
  378 +
  379 +int cpu_alpha_mfpr (CPUState *env, int iprn, uint64_t *valp);
  380 +int cpu_alpha_mtpr (CPUState *env, int iprn, uint64_t val, uint64_t *oldvalp);
  381 +void cpu_loop_exit (void);
  382 +void pal_init (CPUState *env);
  383 +void call_pal (CPUState *env, int palcode);
  384 +
  385 +#endif /* !defined (__CPU_ALPHA_H__) */
target-alpha/exec.h 0 → 100644
  1 +/*
  2 + * Alpha emulation cpu run-time definitions for qemu.
  3 + *
  4 + * Copyright (c) 2007 Jocelyn Mayer
  5 + *
  6 + * This library is free software; you can redistribute it and/or
  7 + * modify it under the terms of the GNU Lesser General Public
  8 + * License as published by the Free Software Foundation; either
  9 + * version 2 of the License, or (at your option) any later version.
  10 + *
  11 + * This library is distributed in the hope that it will be useful,
  12 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14 + * Lesser General Public License for more details.
  15 + *
  16 + * You should have received a copy of the GNU Lesser General Public
  17 + * License along with this library; if not, write to the Free Software
  18 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  19 + */
  20 +
  21 +#if !defined (__ALPHA_EXEC_H__)
  22 +#define __ALPHA_EXEC_H__
  23 +
  24 +#include "config.h"
  25 +
  26 +#include "dyngen-exec.h"
  27 +
  28 +#define TARGET_LONG_BITS 64
  29 +
  30 +register struct CPUAlphaState *env asm(AREG0);
  31 +
  32 +#if TARGET_LONG_BITS > HOST_LONG_BITS
  33 +
  34 +/* no registers can be used */
  35 +#define T0 (env->t0)
  36 +#define T1 (env->t1)
  37 +#define T2 (env->t2)
  38 +
  39 +#else
  40 +
  41 +register uint64_t T0 asm(AREG1);
  42 +register uint64_t T1 asm(AREG2);
  43 +register uint64_t T2 asm(AREG3);
  44 +
  45 +#endif /* TARGET_LONG_BITS > HOST_LONG_BITS */
  46 +
  47 +#define PARAM(n) ((uint64_t)PARAM##n)
  48 +#define SPARAM(n) ((int32_t)PARAM##n)
  49 +#define FT0 (env->ft0)
  50 +#define FT1 (env->ft1)
  51 +#define FT2 (env->ft2)
  52 +#define FP_STATUS (env->fp_status)
  53 +
  54 +#if defined (DEBUG_OP)
  55 +#define RETURN() __asm__ __volatile__("nop" : : : "memory");
  56 +#else
  57 +#define RETURN() __asm__ __volatile__("" : : : "memory");
  58 +#endif
  59 +
  60 +#include "cpu.h"
  61 +#include "exec-all.h"
  62 +
  63 +#if !defined(CONFIG_USER_ONLY)
  64 +#include "softmmu_exec.h"
  65 +#endif /* !defined(CONFIG_USER_ONLY) */
  66 +
  67 +static inline void env_to_regs(void)
  68 +{
  69 +}
  70 +
  71 +static inline void regs_to_env(void)
  72 +{
  73 +}
  74 +
  75 +int cpu_alpha_handle_mmu_fault (CPUState *env, uint64_t address, int rw,
  76 + int is_user, int is_softmmu);
  77 +int cpu_alpha_mfpr (CPUState *env, int iprn, uint64_t *valp);
  78 +int cpu_alpha_mtpr (CPUState *env, int iprn, uint64_t val, uint64_t *oldvalp);
  79 +
  80 +void do_interrupt (CPUState *env);
  81 +
  82 +#endif /* !defined (__ALPHA_EXEC_H__) */
target-alpha/helper.c 0 → 100644
  1 +/*
  2 + * Alpha emulation cpu helpers for qemu.
  3 + *
  4 + * Copyright (c) 2007 Jocelyn Mayer
  5 + *
  6 + * This library is free software; you can redistribute it and/or
  7 + * modify it under the terms of the GNU Lesser General Public
  8 + * License as published by the Free Software Foundation; either
  9 + * version 2 of the License, or (at your option) any later version.
  10 + *
  11 + * This library is distributed in the hope that it will be useful,
  12 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14 + * Lesser General Public License for more details.
  15 + *
  16 + * You should have received a copy of the GNU Lesser General Public
  17 + * License along with this library; if not, write to the Free Software
  18 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  19 + */
  20 +
  21 +#include <stdint.h>
  22 +#include <stdlib.h>
  23 +#include <stdio.h>
  24 +
  25 +#include "cpu.h"
  26 +#include "exec-all.h"
  27 +
  28 +#if defined(CONFIG_USER_ONLY)
  29 +
  30 +int cpu_alpha_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
  31 + int is_user, int is_softmmu)
  32 +{
  33 + if (rw == 2)
  34 + env->exception_index = EXCP_ITB_MISS;
  35 + else
  36 + env->exception_index = EXCP_DFAULT;
  37 + env->ipr[IPR_EXC_ADDR] = address;
  38 +
  39 + return 1;
  40 +}
  41 +
  42 +target_ulong cpu_get_phys_page_debug (CPUState *env, target_ulong addr)
  43 +{
  44 + return addr;
  45 +}
  46 +
  47 +void do_interrupt (CPUState *env)
  48 +{
  49 + env->exception_index = -1;
  50 +}
  51 +
  52 +#else
  53 +
  54 +target_ulong cpu_get_phys_page_debug (CPUState *env, target_ulong addr)
  55 +{
  56 + return -1;
  57 +}
  58 +
  59 +int cpu_alpha_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
  60 + int is_user, int is_softmmu)
  61 +{
  62 + uint32_t opc;
  63 +
  64 + if (rw == 2) {
  65 + /* Instruction translation buffer miss */
  66 + env->exception_index = EXCP_ITB_MISS;
  67 + } else {
  68 + if (env->ipr[IPR_EXC_ADDR] & 1)
  69 + env->exception_index = EXCP_DTB_MISS_PAL;
  70 + else
  71 + env->exception_index = EXCP_DTB_MISS_NATIVE;
  72 + opc = (ldl_code(env->pc) >> 21) << 4;
  73 + if (rw) {
  74 + opc |= 0x9;
  75 + } else {
  76 + opc |= 0x4;
  77 + }
  78 + env->ipr[IPR_MM_STAT] = opc;
  79 + }
  80 +
  81 + return 1;
  82 +}
  83 +
  84 +int cpu_alpha_mfpr (CPUState *env, int iprn, uint64_t *valp)
  85 +{
  86 + uint64_t hwpcb;
  87 + int ret = 0;
  88 +
  89 + hwpcb = env->ipr[IPR_PCBB];
  90 + switch (iprn) {
  91 + case IPR_ASN:
  92 + if (env->features & FEATURE_ASN)
  93 + *valp = env->ipr[IPR_ASN];
  94 + else
  95 + *valp = 0;
  96 + break;
  97 + case IPR_ASTEN:
  98 + *valp = ((int64_t)(env->ipr[IPR_ASTEN] << 60)) >> 60;
  99 + break;
  100 + case IPR_ASTSR:
  101 + *valp = ((int64_t)(env->ipr[IPR_ASTSR] << 60)) >> 60;
  102 + break;
  103 + case IPR_DATFX:
  104 + /* Write only */
  105 + ret = -1;
  106 + break;
  107 + case IPR_ESP:
  108 + if (env->features & FEATURE_SPS)
  109 + *valp = env->ipr[IPR_ESP];
  110 + else
  111 + *valp = ldq_raw(hwpcb + 8);
  112 + break;
  113 + case IPR_FEN:
  114 + *valp = ((int64_t)(env->ipr[IPR_FEN] << 63)) >> 63;
  115 + break;
  116 + case IPR_IPIR:
  117 + /* Write-only */
  118 + ret = -1;
  119 + break;
  120 + case IPR_IPL:
  121 + *valp = ((int64_t)(env->ipr[IPR_IPL] << 59)) >> 59;
  122 + break;
  123 + case IPR_KSP:
  124 + if (!(env->ipr[IPR_EXC_ADDR] & 1)) {
  125 + ret = -1;
  126 + } else {
  127 + if (env->features & FEATURE_SPS)
  128 + *valp = env->ipr[IPR_KSP];
  129 + else
  130 + *valp = ldq_raw(hwpcb + 0);
  131 + }
  132 + break;
  133 + case IPR_MCES:
  134 + *valp = ((int64_t)(env->ipr[IPR_MCES] << 59)) >> 59;
  135 + break;
  136 + case IPR_PERFMON:
  137 + /* Implementation specific */
  138 + *valp = 0;
  139 + break;
  140 + case IPR_PCBB:
  141 + *valp = ((int64_t)env->ipr[IPR_PCBB] << 16) >> 16;
  142 + break;
  143 + case IPR_PRBR:
  144 + *valp = env->ipr[IPR_PRBR];
  145 + break;
  146 + case IPR_PTBR:
  147 + *valp = env->ipr[IPR_PTBR];
  148 + break;
  149 + case IPR_SCBB:
  150 + *valp = (int64_t)((int32_t)env->ipr[IPR_SCBB]);
  151 + break;
  152 + case IPR_SIRR:
  153 + /* Write-only */
  154 + ret = -1;
  155 + break;
  156 + case IPR_SISR:
  157 + *valp = (int64_t)((int16_t)env->ipr[IPR_SISR]);
  158 + case IPR_SSP:
  159 + if (env->features & FEATURE_SPS)
  160 + *valp = env->ipr[IPR_SSP];
  161 + else
  162 + *valp = ldq_raw(hwpcb + 16);
  163 + break;
  164 + case IPR_SYSPTBR:
  165 + if (env->features & FEATURE_VIRBND)
  166 + *valp = env->ipr[IPR_SYSPTBR];
  167 + else
  168 + ret = -1;
  169 + break;
  170 + case IPR_TBCHK:
  171 + if ((env->features & FEATURE_TBCHK)) {
  172 + /* XXX: TODO */
  173 + *valp = 0;
  174 + ret = -1;
  175 + } else {
  176 + ret = -1;
  177 + }
  178 + break;
  179 + case IPR_TBIA:
  180 + /* Write-only */
  181 + ret = -1;
  182 + break;
  183 + case IPR_TBIAP:
  184 + /* Write-only */
  185 + ret = -1;
  186 + break;
  187 + case IPR_TBIS:
  188 + /* Write-only */
  189 + ret = -1;
  190 + break;
  191 + case IPR_TBISD:
  192 + /* Write-only */
  193 + ret = -1;
  194 + break;
  195 + case IPR_TBISI:
  196 + /* Write-only */
  197 + ret = -1;
  198 + break;
  199 + case IPR_USP:
  200 + if (env->features & FEATURE_SPS)
  201 + *valp = env->ipr[IPR_USP];
  202 + else
  203 + *valp = ldq_raw(hwpcb + 24);
  204 + break;
  205 + case IPR_VIRBND:
  206 + if (env->features & FEATURE_VIRBND)
  207 + *valp = env->ipr[IPR_VIRBND];
  208 + else
  209 + ret = -1;
  210 + break;
  211 + case IPR_VPTB:
  212 + *valp = env->ipr[IPR_VPTB];
  213 + break;
  214 + case IPR_WHAMI:
  215 + *valp = env->ipr[IPR_WHAMI];
  216 + break;
  217 + default:
  218 + /* Invalid */
  219 + ret = -1;
  220 + break;
  221 + }
  222 +
  223 + return ret;
  224 +}
  225 +
  226 +int cpu_alpha_mtpr (CPUState *env, int iprn, uint64_t val, uint64_t *oldvalp)
  227 +{
  228 + uint64_t hwpcb, tmp64;
  229 + uint8_t tmp8;
  230 + int ret = 0;
  231 +
  232 + hwpcb = env->ipr[IPR_PCBB];
  233 + switch (iprn) {
  234 + case IPR_ASN:
  235 + /* Read-only */
  236 + ret = -1;
  237 + break;
  238 + case IPR_ASTEN:
  239 + tmp8 = ((int8_t)(env->ipr[IPR_ASTEN] << 4)) >> 4;
  240 + *oldvalp = tmp8;
  241 + tmp8 &= val & 0xF;
  242 + tmp8 |= (val >> 4) & 0xF;
  243 + env->ipr[IPR_ASTEN] &= ~0xF;
  244 + env->ipr[IPR_ASTEN] |= tmp8;
  245 + ret = 1;
  246 + break;
  247 + case IPR_ASTSR:
  248 + tmp8 = ((int8_t)(env->ipr[IPR_ASTSR] << 4)) >> 4;
  249 + *oldvalp = tmp8;
  250 + tmp8 &= val & 0xF;
  251 + tmp8 |= (val >> 4) & 0xF;
  252 + env->ipr[IPR_ASTSR] &= ~0xF;
  253 + env->ipr[IPR_ASTSR] |= tmp8;
  254 + ret = 1;
  255 + case IPR_DATFX:
  256 + env->ipr[IPR_DATFX] &= ~0x1;
  257 + env->ipr[IPR_DATFX] |= val & 1;
  258 + tmp64 = ldq_raw(hwpcb + 56);
  259 + tmp64 &= ~0x8000000000000000ULL;
  260 + tmp64 |= (val & 1) << 63;
  261 + stq_raw(hwpcb + 56, tmp64);
  262 + break;
  263 + case IPR_ESP:
  264 + if (env->features & FEATURE_SPS)
  265 + env->ipr[IPR_ESP] = val;
  266 + else
  267 + stq_raw(hwpcb + 8, val);
  268 + break;
  269 + case IPR_FEN:
  270 + env->ipr[IPR_FEN] = val & 1;
  271 + tmp64 = ldq_raw(hwpcb + 56);
  272 + tmp64 &= ~1;
  273 + tmp64 |= val & 1;
  274 + stq_raw(hwpcb + 56, tmp64);
  275 + break;
  276 + case IPR_IPIR:
  277 + /* XXX: TODO: Send IRQ to CPU #ir[16] */
  278 + break;
  279 + case IPR_IPL:
  280 + *oldvalp = ((int64_t)(env->ipr[IPR_IPL] << 59)) >> 59;
  281 + env->ipr[IPR_IPL] &= ~0x1F;
  282 + env->ipr[IPR_IPL] |= val & 0x1F;
  283 + /* XXX: may issue an interrupt or ASR _now_ */
  284 + ret = 1;
  285 + break;
  286 + case IPR_KSP:
  287 + if (!(env->ipr[IPR_EXC_ADDR] & 1)) {
  288 + ret = -1;
  289 + } else {
  290 + if (env->features & FEATURE_SPS)
  291 + env->ipr[IPR_KSP] = val;
  292 + else
  293 + stq_raw(hwpcb + 0, val);
  294 + }
  295 + break;
  296 + case IPR_MCES:
  297 + env->ipr[IPR_MCES] &= ~((val & 0x7) | 0x18);
  298 + env->ipr[IPR_MCES] |= val & 0x18;
  299 + break;
  300 + case IPR_PERFMON:
  301 + /* Implementation specific */
  302 + *oldvalp = 0;
  303 + ret = 1;
  304 + break;
  305 + case IPR_PCBB:
  306 + /* Read-only */
  307 + ret = -1;
  308 + break;
  309 + case IPR_PRBR:
  310 + env->ipr[IPR_PRBR] = val;
  311 + break;
  312 + case IPR_PTBR:
  313 + /* Read-only */
  314 + ret = -1;
  315 + break;
  316 + case IPR_SCBB:
  317 + env->ipr[IPR_SCBB] = (uint32_t)val;
  318 + break;
  319 + case IPR_SIRR:
  320 + if (val & 0xF) {
  321 + env->ipr[IPR_SISR] |= 1 << (val & 0xF);
  322 + /* XXX: request a software interrupt _now_ */
  323 + }
  324 + break;
  325 + case IPR_SISR:
  326 + /* Read-only */
  327 + ret = -1;
  328 + break;
  329 + case IPR_SSP:
  330 + if (env->features & FEATURE_SPS)
  331 + env->ipr[IPR_SSP] = val;
  332 + else
  333 + stq_raw(hwpcb + 16, val);
  334 + break;
  335 + case IPR_SYSPTBR:
  336 + if (env->features & FEATURE_VIRBND)
  337 + env->ipr[IPR_SYSPTBR] = val;
  338 + else
  339 + ret = -1;
  340 + case IPR_TBCHK:
  341 + /* Read-only */
  342 + ret = -1;
  343 + break;
  344 + case IPR_TBIA:
  345 + tlb_flush(env, 1);
  346 + break;
  347 + case IPR_TBIAP:
  348 + tlb_flush(env, 1);
  349 + break;
  350 + case IPR_TBIS:
  351 + tlb_flush_page(env, val);
  352 + break;
  353 + case IPR_TBISD:
  354 + tlb_flush_page(env, val);
  355 + break;
  356 + case IPR_TBISI:
  357 + tlb_flush_page(env, val);
  358 + break;
  359 + case IPR_USP:
  360 + if (env->features & FEATURE_SPS)
  361 + env->ipr[IPR_USP] = val;
  362 + else
  363 + stq_raw(hwpcb + 24, val);
  364 + break;
  365 + case IPR_VIRBND:
  366 + if (env->features & FEATURE_VIRBND)
  367 + env->ipr[IPR_VIRBND] = val;
  368 + else
  369 + ret = -1;
  370 + break;
  371 + case IPR_VPTB:
  372 + env->ipr[IPR_VPTB] = val;
  373 + break;
  374 + case IPR_WHAMI:
  375 + /* Read-only */
  376 + ret = -1;
  377 + break;
  378 + default:
  379 + /* Invalid */
  380 + ret = -1;
  381 + break;
  382 + }
  383 +
  384 + return ret;
  385 +}
  386 +
  387 +void do_interrupt (CPUState *env)
  388 +{
  389 + int excp;
  390 +
  391 + env->ipr[IPR_EXC_ADDR] = env->pc | 1;
  392 + excp = env->exception_index;
  393 + env->exception_index = 0;
  394 + env->error_code = 0;
  395 + /* XXX: disable interrupts and memory mapping */
  396 + if (env->ipr[IPR_PAL_BASE] != -1ULL) {
  397 + /* We use native PALcode */
  398 + env->pc = env->ipr[IPR_PAL_BASE] + excp;
  399 + } else {
  400 + /* We use emulated PALcode */
  401 + call_pal(env);
  402 + /* Emulate REI */
  403 + env->pc = env->ipr[IPR_EXC_ADDR] & ~7;
  404 + env->ipr[IPR_EXC_ADDR] = env->ipr[IPR_EXC_ADDR] & 1;
  405 + /* XXX: re-enable interrupts and memory mapping */
  406 + }
  407 +}
  408 +#endif
  409 +
  410 +void cpu_dump_state (CPUState *env, FILE *f,
  411 + int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
  412 + int flags)
  413 +{
  414 + static unsigned char *linux_reg_names[] = {
  415 + "v0 ", "t0 ", "t1 ", "t2 ", "t3 ", "t4 ", "t5 ", "t6 ",
  416 + "t7 ", "s0 ", "s1 ", "s2 ", "s3 ", "s4 ", "s5 ", "fp ",
  417 + "a0 ", "a1 ", "a2 ", "a3 ", "a4 ", "a5 ", "t8 ", "t9 ",
  418 + "t10", "t11", "ra ", "t12", "at ", "gp ", "sp ", "zero",
  419 + };
  420 + int i;
  421 +
  422 + cpu_fprintf(f, " PC " TARGET_FMT_lx " PS " TARGET_FMT_lx "\n",
  423 + env->pc, env->ps);
  424 + for (i = 0; i < 31; i++) {
  425 + cpu_fprintf(f, "IR%02d %s " TARGET_FMT_lx " ", i,
  426 + linux_reg_names[i], env->ir[i]);
  427 + if ((i % 3) == 2)
  428 + cpu_fprintf(f, "\n");
  429 + }
  430 + cpu_fprintf(f, "\n");
  431 + for (i = 0; i < 31; i++) {
  432 + cpu_fprintf(f, "FIR%02d " TARGET_FMT_lx " ", i,
  433 + *((uint64_t *)(&env->fir[i])));
  434 + if ((i % 3) == 2)
  435 + cpu_fprintf(f, "\n");
  436 + }
  437 + cpu_fprintf(f, "FT " TARGET_FMT_lx " " TARGET_FMT_lx " " TARGET_FMT_lx,
  438 + *((uint64_t *)(&env->ft0)), *((uint64_t *)(&env->ft1)),
  439 + *((uint64_t *)(&env->ft2)));
  440 + cpu_fprintf(f, "\nMEM " TARGET_FMT_lx " %d %d\n",
  441 + ldq_raw(0x000000004007df60ULL),
  442 + (uint8_t *)(&env->ft0), (uint8_t *)(&env->fir[0]));
  443 +}
  444 +
  445 +void cpu_dump_EA (target_ulong EA)
  446 +{
  447 + FILE *f;
  448 +
  449 + if (logfile)
  450 + f = logfile;
  451 + else
  452 + f = stdout;
  453 + fprintf(f, "Memory access at address " TARGET_FMT_lx "\n", EA);
  454 +}
target-alpha/op.c 0 → 100644
  1 +/*
  2 + * Alpha emulation cpu micro-operations for qemu.
  3 + *
  4 + * Copyright (c) 2007 Jocelyn Mayer
  5 + *
  6 + * This library is free software; you can redistribute it and/or
  7 + * modify it under the terms of the GNU Lesser General Public
  8 + * License as published by the Free Software Foundation; either
  9 + * version 2 of the License, or (at your option) any later version.
  10 + *
  11 + * This library is distributed in the hope that it will be useful,
  12 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14 + * Lesser General Public License for more details.
  15 + *
  16 + * You should have received a copy of the GNU Lesser General Public
  17 + * License along with this library; if not, write to the Free Software
  18 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  19 + */
  20 +
  21 +#define DEBUG_OP
  22 +
  23 +#include "config.h"
  24 +#include "exec.h"
  25 +
  26 +#include "op_helper.h"
  27 +
  28 +#define REG 0
  29 +#include "op_template.h"
  30 +
  31 +#define REG 1
  32 +#include "op_template.h"
  33 +
  34 +#define REG 2
  35 +#include "op_template.h"
  36 +
  37 +#define REG 3
  38 +#include "op_template.h"
  39 +
  40 +#define REG 4
  41 +#include "op_template.h"
  42 +
  43 +#define REG 5
  44 +#include "op_template.h"
  45 +
  46 +#define REG 6
  47 +#include "op_template.h"
  48 +
  49 +#define REG 7
  50 +#include "op_template.h"
  51 +
  52 +#define REG 8
  53 +#include "op_template.h"
  54 +
  55 +#define REG 9
  56 +#include "op_template.h"
  57 +
  58 +#define REG 10
  59 +#include "op_template.h"
  60 +
  61 +#define REG 11
  62 +#include "op_template.h"
  63 +
  64 +#define REG 12
  65 +#include "op_template.h"
  66 +
  67 +#define REG 13
  68 +#include "op_template.h"
  69 +
  70 +#define REG 14
  71 +#include "op_template.h"
  72 +
  73 +#define REG 15
  74 +#include "op_template.h"
  75 +
  76 +#define REG 16
  77 +#include "op_template.h"
  78 +
  79 +#define REG 17
  80 +#include "op_template.h"
  81 +
  82 +#define REG 18
  83 +#include "op_template.h"
  84 +
  85 +#define REG 19
  86 +#include "op_template.h"
  87 +
  88 +#define REG 20
  89 +#include "op_template.h"
  90 +
  91 +#define REG 21
  92 +#include "op_template.h"
  93 +
  94 +#define REG 22
  95 +#include "op_template.h"
  96 +
  97 +#define REG 23
  98 +#include "op_template.h"
  99 +
  100 +#define REG 24
  101 +#include "op_template.h"
  102 +
  103 +#define REG 25
  104 +#include "op_template.h"
  105 +
  106 +#define REG 26
  107 +#include "op_template.h"
  108 +
  109 +#define REG 27
  110 +#include "op_template.h"
  111 +
  112 +#define REG 28
  113 +#include "op_template.h"
  114 +
  115 +#define REG 29
  116 +#include "op_template.h"
  117 +
  118 +#define REG 30
  119 +#include "op_template.h"
  120 +
  121 +#define REG 31
  122 +#include "op_template.h"
  123 +
  124 +/* Debug stuff */
  125 +void OPPROTO op_no_op (void)
  126 +{
  127 +#if !defined (DEBUG_OP)
  128 + __asm__ __volatile__("nop" : : : "memory");
  129 +#endif
  130 + RETURN();
  131 +}
  132 +
  133 +void OPPROTO op_tb_flush (void)
  134 +{
  135 + helper_tb_flush();
  136 + RETURN();
  137 +}
  138 +
  139 +/* Load and stores */
  140 +#define MEMSUFFIX _raw
  141 +#include "op_mem.h"
  142 +#if !defined(CONFIG_USER_ONLY)
  143 +#define MEMSUFFIX _user
  144 +#include "op_mem.h"
  145 +#define MEMSUFFIX _kernel
  146 +#include "op_mem.h"
  147 +/* Those are used for supervisor, executive and pal modes */
  148 +#define MEMSUFFIX _data
  149 +#include "op_mem.h"
  150 +#endif
  151 +
  152 +/* Special operation for load and store */
  153 +void OPPROTO op_n7 (void)
  154 +{
  155 + T0 &= ~(uint64_t)0x7;
  156 + RETURN();
  157 +}
  158 +
  159 +/* Misc */
  160 +void OPPROTO op_excp (void)
  161 +{
  162 + helper_excp(PARAM(1), PARAM(2));
  163 + RETURN();
  164 +}
  165 +
  166 +void OPPROTO op_load_amask (void)
  167 +{
  168 + helper_amask();
  169 + RETURN();
  170 +}
  171 +
  172 +void OPPROTO op_load_pcc (void)
  173 +{
  174 + helper_load_pcc();
  175 + RETURN();
  176 +}
  177 +
  178 +void OPPROTO op_load_implver (void)
  179 +{
  180 + helper_load_implver();
  181 + RETURN();
  182 +}
  183 +
  184 +void OPPROTO op_load_fpcr (void)
  185 +{
  186 + helper_load_fpcr();
  187 + RETURN();
  188 +}
  189 +
  190 +void OPPROTO op_store_fpcr (void)
  191 +{
  192 + helper_store_fpcr();
  193 + RETURN();
  194 +}
  195 +
  196 +void OPPROTO op_load_irf (void)
  197 +{
  198 + helper_load_irf();
  199 + RETURN();
  200 +}
  201 +
  202 +void OPPROTO op_set_irf (void)
  203 +{
  204 + helper_set_irf();
  205 + RETURN();
  206 +}
  207 +
  208 +void OPPROTO op_clear_irf (void)
  209 +{
  210 + helper_clear_irf();
  211 + RETURN();
  212 +}
  213 +
  214 +void OPPROTO op_exit_tb (void)
  215 +{
  216 + EXIT_TB();
  217 +}
  218 +
  219 +/* Arithmetic */
  220 +void OPPROTO op_addq (void)
  221 +{
  222 + T0 += T1;
  223 + RETURN();
  224 +}
  225 +
  226 +void OPPROTO op_addqv (void)
  227 +{
  228 + helper_addqv();
  229 + RETURN();
  230 +}
  231 +
  232 +void OPPROTO op_addl (void)
  233 +{
  234 + T0 = (int64_t)((int32_t)(T0 + T1));
  235 + RETURN();
  236 +}
  237 +
  238 +void OPPROTO op_addlv (void)
  239 +{
  240 + helper_addlv();
  241 + RETURN();
  242 +}
  243 +
  244 +void OPPROTO op_subq (void)
  245 +{
  246 + T0 -= T1;
  247 + RETURN();
  248 +}
  249 +
  250 +void OPPROTO op_subqv (void)
  251 +{
  252 + helper_subqv();
  253 + RETURN();
  254 +}
  255 +
  256 +void OPPROTO op_subl (void)
  257 +{
  258 + T0 = (int64_t)((int32_t)(T0 - T1));
  259 + RETURN();
  260 +}
  261 +
  262 +void OPPROTO op_sublv (void)
  263 +{
  264 + helper_sublv();
  265 + RETURN();
  266 +}
  267 +
  268 +void OPPROTO op_s4 (void)
  269 +{
  270 + T0 <<= 2;
  271 + RETURN();
  272 +}
  273 +
  274 +void OPPROTO op_s8 (void)
  275 +{
  276 + T0 <<= 3;
  277 + RETURN();
  278 +}
  279 +
  280 +void OPPROTO op_mull (void)
  281 +{
  282 + T0 = (int64_t)((int32_t)T0 * (int32_t)T1);
  283 + RETURN();
  284 +}
  285 +
  286 +void OPPROTO op_mullv (void)
  287 +{
  288 + helper_mullv();
  289 + RETURN();
  290 +}
  291 +
  292 +void OPPROTO op_mulq (void)
  293 +{
  294 + T0 *= T1;
  295 + RETURN();
  296 +}
  297 +
  298 +void OPPROTO op_mulqv (void)
  299 +{
  300 + helper_mulqv();
  301 + RETURN();
  302 +}
  303 +
  304 +void OPPROTO op_umulh (void)
  305 +{
  306 + helper_umulh();
  307 + RETURN();
  308 +}
  309 +
  310 +/* Logical */
  311 +void OPPROTO op_and (void)
  312 +{
  313 + T0 &= T1;
  314 + RETURN();
  315 +}
  316 +
  317 +void OPPROTO op_bic (void)
  318 +{
  319 + T0 &= ~T1;
  320 + RETURN();
  321 +}
  322 +
  323 +void OPPROTO op_bis (void)
  324 +{
  325 + T0 |= T1;
  326 + RETURN();
  327 +}
  328 +
  329 +void OPPROTO op_eqv (void)
  330 +{
  331 + T0 ^= ~T1;
  332 + RETURN();
  333 +}
  334 +
  335 +void OPPROTO op_ornot (void)
  336 +{
  337 + T0 |= ~T1;
  338 + RETURN();
  339 +}
  340 +
  341 +void OPPROTO op_xor (void)
  342 +{
  343 + T0 ^= T1;
  344 + RETURN();
  345 +}
  346 +
  347 +void OPPROTO op_sll (void)
  348 +{
  349 + T0 <<= T1;
  350 + RETURN();
  351 +}
  352 +
  353 +void OPPROTO op_srl (void)
  354 +{
  355 + T0 >>= T1;
  356 + RETURN();
  357 +}
  358 +
  359 +void OPPROTO op_sra (void)
  360 +{
  361 + T0 = (int64_t)T0 >> T1;
  362 + RETURN();
  363 +}
  364 +
  365 +void OPPROTO op_sextb (void)
  366 +{
  367 + T0 = (int64_t)((int8_t)T0);
  368 + RETURN();
  369 +}
  370 +
  371 +void OPPROTO op_sextw (void)
  372 +{
  373 + T0 = (int64_t)((int16_t)T0);
  374 + RETURN();
  375 +
  376 +}
  377 +
  378 +void OPPROTO op_ctpop (void)
  379 +{
  380 + helper_ctpop();
  381 + RETURN();
  382 +}
  383 +
  384 +void OPPROTO op_ctlz (void)
  385 +{
  386 + helper_ctlz();
  387 + RETURN();
  388 +}
  389 +
  390 +void OPPROTO op_cttz (void)
  391 +{
  392 + helper_cttz();
  393 + RETURN();
  394 +}
  395 +
  396 +void OPPROTO op_mskbl (void)
  397 +{
  398 + helper_mskbl();
  399 + RETURN();
  400 +}
  401 +
  402 +void OPPROTO op_extbl (void)
  403 +{
  404 + helper_extbl();
  405 + RETURN();
  406 +}
  407 +
  408 +void OPPROTO op_insbl (void)
  409 +{
  410 + helper_insbl();
  411 + RETURN();
  412 +}
  413 +
  414 +void OPPROTO op_mskwl (void)
  415 +{
  416 + helper_mskwl();
  417 + RETURN();
  418 +}
  419 +
  420 +void OPPROTO op_extwl (void)
  421 +{
  422 + helper_extwl();
  423 + RETURN();
  424 +}
  425 +
  426 +void OPPROTO op_inswl (void)
  427 +{
  428 + helper_inswl();
  429 + RETURN();
  430 +}
  431 +
  432 +void OPPROTO op_mskll (void)
  433 +{
  434 + helper_mskll();
  435 + RETURN();
  436 +}
  437 +
  438 +void OPPROTO op_extll (void)
  439 +{
  440 + helper_extll();
  441 + RETURN();
  442 +}
  443 +
  444 +void OPPROTO op_insll (void)
  445 +{
  446 + helper_insll();
  447 + RETURN();
  448 +}
  449 +
  450 +void OPPROTO op_zap (void)
  451 +{
  452 + helper_zap();
  453 + RETURN();
  454 +}
  455 +
  456 +void OPPROTO op_zapnot (void)
  457 +{
  458 + helper_zapnot();
  459 + RETURN();
  460 +}
  461 +
  462 +void OPPROTO op_mskql (void)
  463 +{
  464 + helper_mskql();
  465 + RETURN();
  466 +}
  467 +
  468 +void OPPROTO op_extql (void)
  469 +{
  470 + helper_extql();
  471 + RETURN();
  472 +}
  473 +
  474 +void OPPROTO op_insql (void)
  475 +{
  476 + helper_insql();
  477 + RETURN();
  478 +}
  479 +
  480 +void OPPROTO op_mskwh (void)
  481 +{
  482 + helper_mskwh();
  483 + RETURN();
  484 +}
  485 +
  486 +void OPPROTO op_inswh (void)
  487 +{
  488 + helper_inswh();
  489 + RETURN();
  490 +}
  491 +
  492 +void OPPROTO op_extwh (void)
  493 +{
  494 + helper_extwh();
  495 + RETURN();
  496 +}
  497 +
  498 +void OPPROTO op_msklh (void)
  499 +{
  500 + helper_msklh();
  501 + RETURN();
  502 +}
  503 +
  504 +void OPPROTO op_inslh (void)
  505 +{
  506 + helper_inslh();
  507 + RETURN();
  508 +}
  509 +
  510 +void OPPROTO op_extlh (void)
  511 +{
  512 + helper_extlh();
  513 + RETURN();
  514 +}
  515 +
  516 +void OPPROTO op_mskqh (void)
  517 +{
  518 + helper_mskqh();
  519 + RETURN();
  520 +}
  521 +
  522 +void OPPROTO op_insqh (void)
  523 +{
  524 + helper_insqh();
  525 + RETURN();
  526 +}
  527 +
  528 +void OPPROTO op_extqh (void)
  529 +{
  530 + helper_extqh();
  531 + RETURN();
  532 +}
  533 +
  534 +/* Tests */
  535 +void OPPROTO op_cmpult (void)
  536 +{
  537 + if (T0 < T1)
  538 + T0 = 1;
  539 + else
  540 + T0 = 0;
  541 + RETURN();
  542 +}
  543 +
  544 +void OPPROTO op_cmpule (void)
  545 +{
  546 + if (T0 <= T1)
  547 + T0 = 1;
  548 + else
  549 + T0 = 0;
  550 + RETURN();
  551 +}
  552 +
  553 +void OPPROTO op_cmpeq (void)
  554 +{
  555 + if (T0 == T1)
  556 + T0 = 1;
  557 + else
  558 + T0 = 0;
  559 + RETURN();
  560 +}
  561 +
  562 +void OPPROTO op_cmplt (void)
  563 +{
  564 + if ((int64_t)T0 < (int64_t)T1)
  565 + T0 = 1;
  566 + else
  567 + T0 = 0;
  568 + RETURN();
  569 +}
  570 +
  571 +void OPPROTO op_cmple (void)
  572 +{
  573 + if ((int64_t)T0 <= (int64_t)T1)
  574 + T0 = 1;
  575 + else
  576 + T0 = 0;
  577 + RETURN();
  578 +}
  579 +
  580 +void OPPROTO op_cmpbge (void)
  581 +{
  582 + helper_cmpbge();
  583 + RETURN();
  584 +}
  585 +
  586 +void OPPROTO op_cmpeqz (void)
  587 +{
  588 + if (T0 == 0)
  589 + T0 = 1;
  590 + else
  591 + T0 = 0;
  592 + RETURN();
  593 +}
  594 +
  595 +void OPPROTO op_cmpnez (void)
  596 +{
  597 + if (T0 != 0)
  598 + T0 = 1;
  599 + else
  600 + T0 = 0;
  601 + RETURN();
  602 +}
  603 +
  604 +void OPPROTO op_cmpltz (void)
  605 +{
  606 + if ((int64_t)T0 < 0)
  607 + T0 = 1;
  608 + else
  609 + T0 = 0;
  610 + RETURN();
  611 +}
  612 +
  613 +void OPPROTO op_cmplez (void)
  614 +{
  615 + if ((int64_t)T0 <= 0)
  616 + T0 = 1;
  617 + else
  618 + T0 = 0;
  619 + RETURN();
  620 +}
  621 +
  622 +void OPPROTO op_cmpgtz (void)
  623 +{
  624 + if ((int64_t)T0 > 0)
  625 + T0 = 1;
  626 + else
  627 + T0 = 0;
  628 + RETURN();
  629 +}
  630 +
  631 +void OPPROTO op_cmpgez (void)
  632 +{
  633 + if ((int64_t)T0 >= 0)
  634 + T0 = 1;
  635 + else
  636 + T0 = 0;
  637 + RETURN();
  638 +}
  639 +
  640 +void OPPROTO op_cmplbs (void)
  641 +{
  642 + T0 &= 1;
  643 + RETURN();
  644 +}
  645 +
  646 +void OPPROTO op_cmplbc (void)
  647 +{
  648 + T0 = (~T0) & 1;
  649 + RETURN();
  650 +}
  651 +
  652 +/* Branches */
  653 +void OPPROTO op_branch (void)
  654 +{
  655 + env->pc = T0 & ~3;
  656 + RETURN();
  657 +}
  658 +
  659 +void OPPROTO op_addq1 (void)
  660 +{
  661 + T1 += T0;
  662 + RETURN();
  663 +}
  664 +
  665 +#if 0 // Qemu does not know how to do this...
  666 +void OPPROTO op_bcond (void)
  667 +{
  668 + if (T0)
  669 + env->pc = T1 & ~3;
  670 + else
  671 + env->pc = PARAM(1);
  672 + RETURN();
  673 +}
  674 +#else
  675 +void OPPROTO op_bcond (void)
  676 +{
  677 + if (T0)
  678 + env->pc = T1 & ~3;
  679 + else
  680 + env->pc = ((uint64_t)PARAM(1) << 32) | (uint64_t)PARAM(2);
  681 + RETURN();
  682 +}
  683 +#endif
  684 +
  685 +#if 0 // Qemu does not know how to do this...
  686 +void OPPROTO op_update_pc (void)
  687 +{
  688 + env->pc = PARAM(1);
  689 + RETURN();
  690 +}
  691 +#else
  692 +void OPPROTO op_update_pc (void)
  693 +{
  694 + env->pc = ((uint64_t)PARAM(1) << 32) | (uint64_t)PARAM(2);
  695 + RETURN();
  696 +}
  697 +#endif
  698 +
  699 +/* Optimization for 32 bits hosts architectures */
  700 +void OPPROTO op_update_pc32 (void)
  701 +{
  702 + env->pc = (uint64_t)PARAM(1);
  703 + RETURN();
  704 +}
  705 +
  706 +/* IEEE floating point arithmetic */
  707 +/* S floating (single) */
  708 +void OPPROTO op_adds (void)
  709 +{
  710 + FT0 = float32_add(FT0, FT1, &FP_STATUS);
  711 + RETURN();
  712 +}
  713 +
  714 +void OPPROTO op_subs (void)
  715 +{
  716 + FT0 = float32_sub(FT0, FT1, &FP_STATUS);
  717 + RETURN();
  718 +}
  719 +
  720 +void OPPROTO op_muls (void)
  721 +{
  722 + FT0 = float32_mul(FT0, FT1, &FP_STATUS);
  723 + RETURN();
  724 +}
  725 +
  726 +void OPPROTO op_divs (void)
  727 +{
  728 + FT0 = float32_div(FT0, FT1, &FP_STATUS);
  729 + RETURN();
  730 +}
  731 +
  732 +void OPPROTO op_sqrts (void)
  733 +{
  734 + helper_sqrts();
  735 + RETURN();
  736 +}
  737 +
  738 +void OPPROTO op_cpys (void)
  739 +{
  740 + helper_cpys();
  741 + RETURN();
  742 +}
  743 +
  744 +void OPPROTO op_cpysn (void)
  745 +{
  746 + helper_cpysn();
  747 + RETURN();
  748 +}
  749 +
  750 +void OPPROTO op_cpyse (void)
  751 +{
  752 + helper_cpyse();
  753 + RETURN();
  754 +}
  755 +
  756 +void OPPROTO op_itofs (void)
  757 +{
  758 + helper_itofs();
  759 + RETURN();
  760 +}
  761 +
  762 +void OPPROTO op_ftois (void)
  763 +{
  764 + helper_ftois();
  765 + RETURN();
  766 +}
  767 +
  768 +/* T floating (double) */
  769 +void OPPROTO op_addt (void)
  770 +{
  771 + FT0 = float64_add(FT0, FT1, &FP_STATUS);
  772 + RETURN();
  773 +}
  774 +
  775 +void OPPROTO op_subt (void)
  776 +{
  777 + FT0 = float64_sub(FT0, FT1, &FP_STATUS);
  778 + RETURN();
  779 +}
  780 +
  781 +void OPPROTO op_mult (void)
  782 +{
  783 + FT0 = float64_mul(FT0, FT1, &FP_STATUS);
  784 + RETURN();
  785 +}
  786 +
  787 +void OPPROTO op_divt (void)
  788 +{
  789 + FT0 = float64_div(FT0, FT1, &FP_STATUS);
  790 + RETURN();
  791 +}
  792 +
  793 +void OPPROTO op_sqrtt (void)
  794 +{
  795 + helper_sqrtt();
  796 + RETURN();
  797 +}
  798 +
  799 +void OPPROTO op_cmptun (void)
  800 +{
  801 + helper_cmptun();
  802 + RETURN();
  803 +}
  804 +
  805 +void OPPROTO op_cmpteq (void)
  806 +{
  807 + helper_cmpteq();
  808 + RETURN();
  809 +}
  810 +
  811 +void OPPROTO op_cmptle (void)
  812 +{
  813 + helper_cmptle();
  814 + RETURN();
  815 +}
  816 +
  817 +void OPPROTO op_cmptlt (void)
  818 +{
  819 + helper_cmptlt();
  820 + RETURN();
  821 +}
  822 +
  823 +void OPPROTO op_itoft (void)
  824 +{
  825 + helper_itoft();
  826 + RETURN();
  827 +}
  828 +
  829 +void OPPROTO op_ftoit (void)
  830 +{
  831 + helper_ftoit();
  832 + RETURN();
  833 +}
  834 +
  835 +/* VAX floating point arithmetic */
  836 +/* F floating */
  837 +void OPPROTO op_addf (void)
  838 +{
  839 + helper_addf();
  840 + RETURN();
  841 +}
  842 +
  843 +void OPPROTO op_subf (void)
  844 +{
  845 + helper_subf();
  846 + RETURN();
  847 +}
  848 +
  849 +void OPPROTO op_mulf (void)
  850 +{
  851 + helper_mulf();
  852 + RETURN();
  853 +}
  854 +
  855 +void OPPROTO op_divf (void)
  856 +{
  857 + helper_divf();
  858 + RETURN();
  859 +}
  860 +
  861 +void OPPROTO op_sqrtf (void)
  862 +{
  863 + helper_sqrtf();
  864 + RETURN();
  865 +}
  866 +
  867 +void OPPROTO op_cmpfeq (void)
  868 +{
  869 + helper_cmpfeq();
  870 + RETURN();
  871 +}
  872 +
  873 +void OPPROTO op_cmpfne (void)
  874 +{
  875 + helper_cmpfne();
  876 + RETURN();
  877 +}
  878 +
  879 +void OPPROTO op_cmpflt (void)
  880 +{
  881 + helper_cmpflt();
  882 + RETURN();
  883 +}
  884 +
  885 +void OPPROTO op_cmpfle (void)
  886 +{
  887 + helper_cmpfle();
  888 + RETURN();
  889 +}
  890 +
  891 +void OPPROTO op_cmpfgt (void)
  892 +{
  893 + helper_cmpfgt();
  894 + RETURN();
  895 +}
  896 +
  897 +void OPPROTO op_cmpfge (void)
  898 +{
  899 + helper_cmpfge();
  900 + RETURN();
  901 +}
  902 +
  903 +void OPPROTO op_itoff (void)
  904 +{
  905 + helper_itoff();
  906 + RETURN();
  907 +}
  908 +
  909 +/* G floating */
  910 +void OPPROTO op_addg (void)
  911 +{
  912 + helper_addg();
  913 + RETURN();
  914 +}
  915 +
  916 +void OPPROTO op_subg (void)
  917 +{
  918 + helper_subg();
  919 + RETURN();
  920 +}
  921 +
  922 +void OPPROTO op_mulg (void)
  923 +{
  924 + helper_mulg();
  925 + RETURN();
  926 +}
  927 +
  928 +void OPPROTO op_divg (void)
  929 +{
  930 + helper_divg();
  931 + RETURN();
  932 +}
  933 +
  934 +void OPPROTO op_sqrtg (void)
  935 +{
  936 + helper_sqrtg();
  937 + RETURN();
  938 +}
  939 +
  940 +void OPPROTO op_cmpgeq (void)
  941 +{
  942 + helper_cmpgeq();
  943 + RETURN();
  944 +}
  945 +
  946 +void OPPROTO op_cmpglt (void)
  947 +{
  948 + helper_cmpglt();
  949 + RETURN();
  950 +}
  951 +
  952 +void OPPROTO op_cmpgle (void)
  953 +{
  954 + helper_cmpgle();
  955 + RETURN();
  956 +}
  957 +
  958 +/* Floating point format conversion */
  959 +void OPPROTO op_cvtst (void)
  960 +{
  961 + FT0 = (float)FT0;
  962 + RETURN();
  963 +}
  964 +
  965 +void OPPROTO op_cvtqs (void)
  966 +{
  967 + helper_cvtqs();
  968 + RETURN();
  969 +}
  970 +
  971 +void OPPROTO op_cvtts (void)
  972 +{
  973 + FT0 = (float)FT0;
  974 + RETURN();
  975 +}
  976 +
  977 +void OPPROTO op_cvttq (void)
  978 +{
  979 + helper_cvttq();
  980 + RETURN();
  981 +}
  982 +
  983 +void OPPROTO op_cvtqt (void)
  984 +{
  985 + helper_cvtqt();
  986 + RETURN();
  987 +}
  988 +
  989 +void OPPROTO op_cvtqf (void)
  990 +{
  991 + helper_cvtqf();
  992 + RETURN();
  993 +}
  994 +
  995 +void OPPROTO op_cvtgf (void)
  996 +{
  997 + helper_cvtgf();
  998 + RETURN();
  999 +}
  1000 +
  1001 +void OPPROTO op_cvtgd (void)
  1002 +{
  1003 + helper_cvtgd();
  1004 + RETURN();
  1005 +}
  1006 +
  1007 +void OPPROTO op_cvtgq (void)
  1008 +{
  1009 + helper_cvtgq();
  1010 + RETURN();
  1011 +}
  1012 +
  1013 +void OPPROTO op_cvtqg (void)
  1014 +{
  1015 + helper_cvtqg();
  1016 + RETURN();
  1017 +}
  1018 +
  1019 +void OPPROTO op_cvtdg (void)
  1020 +{
  1021 + helper_cvtdg();
  1022 + RETURN();
  1023 +}
  1024 +
  1025 +void OPPROTO op_cvtlq (void)
  1026 +{
  1027 + helper_cvtlq();
  1028 + RETURN();
  1029 +}
  1030 +
  1031 +void OPPROTO op_cvtql (void)
  1032 +{
  1033 + helper_cvtql();
  1034 + RETURN();
  1035 +}
  1036 +
  1037 +void OPPROTO op_cvtqlv (void)
  1038 +{
  1039 + helper_cvtqlv();
  1040 + RETURN();
  1041 +}
  1042 +
  1043 +void OPPROTO op_cvtqlsv (void)
  1044 +{
  1045 + helper_cvtqlsv();
  1046 + RETURN();
  1047 +}
  1048 +
  1049 +/* PALcode support special instructions */
  1050 +#if !defined (CONFIG_USER_ONLY)
  1051 +void OPPROTO op_hw_rei (void)
  1052 +{
  1053 + env->pc = env->ipr[IPR_EXC_ADDR] & ~3;
  1054 + env->ipr[IPR_EXC_ADDR] = env->ipr[IPR_EXC_ADDR] & 1;
  1055 + /* XXX: re-enable interrupts and memory mapping */
  1056 + RETURN();
  1057 +}
  1058 +
  1059 +void OPPROTO op_hw_ret (void)
  1060 +{
  1061 + env->pc = T0 & ~3;
  1062 + env->ipr[IPR_EXC_ADDR] = T0 & 1;
  1063 + /* XXX: re-enable interrupts and memory mapping */
  1064 + RETURN();
  1065 +}
  1066 +
  1067 +void OPPROTO op_mfpr (void)
  1068 +{
  1069 + helper_mfpr(PARAM(1));
  1070 + RETURN();
  1071 +}
  1072 +
  1073 +void OPPROTO op_mtpr (void)
  1074 +{
  1075 + helper_mtpr(PARAM(1));
  1076 + RETURN();
  1077 +}
  1078 +
  1079 +void OPPROTO op_set_alt_mode (void)
  1080 +{
  1081 + env->saved_mode = env->ps & 0xC;
  1082 + env->ps = (env->ps & ~0xC) | (env->ipr[IPR_ALT_MODE] & 0xC);
  1083 + RETURN();
  1084 +}
  1085 +
  1086 +void OPPROTO op_restore_mode (void)
  1087 +{
  1088 + env->ps = (env->ps & ~0xC) | env->saved_mode;
  1089 + RETURN();
  1090 +}
  1091 +
  1092 +void OPPROTO op_ld_phys_to_virt (void)
  1093 +{
  1094 + helper_ld_phys_to_virt();
  1095 + RETURN();
  1096 +}
  1097 +
  1098 +void OPPROTO op_st_phys_to_virt (void)
  1099 +{
  1100 + helper_st_phys_to_virt();
  1101 + RETURN();
  1102 +}
  1103 +#endif /* !defined (CONFIG_USER_ONLY) */
target-alpha/op_helper.c 0 → 100644
  1 +/*
  2 + * Alpha emulation cpu micro-operations helpers for qemu.
  3 + *
  4 + * Copyright (c) 2007 Jocelyn Mayer
  5 + *
  6 + * This library is free software; you can redistribute it and/or
  7 + * modify it under the terms of the GNU Lesser General Public
  8 + * License as published by the Free Software Foundation; either
  9 + * version 2 of the License, or (at your option) any later version.
  10 + *
  11 + * This library is distributed in the hope that it will be useful,
  12 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14 + * Lesser General Public License for more details.
  15 + *
  16 + * You should have received a copy of the GNU Lesser General Public
  17 + * License along with this library; if not, write to the Free Software
  18 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  19 + */
  20 +
  21 +#include "exec.h"
  22 +#include "softfloat.h"
  23 +
  24 +#include "op_helper.h"
  25 +
  26 +#define MEMSUFFIX _raw
  27 +#include "op_helper_mem.h"
  28 +
  29 +#if !defined(CONFIG_USER_ONLY)
  30 +#define MEMSUFFIX _user
  31 +#include "op_helper_mem.h"
  32 +
  33 +#define MEMSUFFIX _kernel
  34 +#include "op_helper_mem.h"
  35 +
  36 +/* Those are used for supervisor and executive modes */
  37 +#define MEMSUFFIX _data
  38 +#include "op_helper_mem.h"
  39 +#endif
  40 +
  41 +void helper_tb_flush (void)
  42 +{
  43 + tlb_flush(env, 1);
  44 +}
  45 +
  46 +void cpu_dump_EA (target_ulong EA);
  47 +void helper_print_mem_EA (target_ulong EA)
  48 +{
  49 + cpu_dump_EA(EA);
  50 +}
  51 +
  52 +/*****************************************************************************/
  53 +/* Exceptions processing helpers */
  54 +void helper_excp (uint32_t excp, uint32_t error)
  55 +{
  56 + env->exception_index = excp;
  57 + env->error_code = error;
  58 + cpu_loop_exit();
  59 +}
  60 +
  61 +void helper_amask (void)
  62 +{
  63 + switch (env->implver) {
  64 + case IMPLVER_2106x:
  65 + /* EV4, EV45, LCA, LCA45 & EV5 */
  66 + break;
  67 + case IMPLVER_21164:
  68 + case IMPLVER_21264:
  69 + case IMPLVER_21364:
  70 + T0 &= ~env->amask;
  71 + break;
  72 + }
  73 +}
  74 +
  75 +void helper_load_pcc (void)
  76 +{
  77 + /* XXX: TODO */
  78 + T0 = 0;
  79 +}
  80 +
  81 +void helper_load_implver (void)
  82 +{
  83 + T0 = env->implver;
  84 +}
  85 +
  86 +void helper_load_fpcr (void)
  87 +{
  88 + T0 = 0;
  89 +#ifdef CONFIG_SOFTFLOAT
  90 + T0 |= env->fp_status.float_exception_flags << 52;
  91 + if (env->fp_status.float_exception_flags)
  92 + T0 |= 1ULL << 63;
  93 + env->ipr[IPR_EXC_SUM] &= ~0x3E:
  94 + env->ipr[IPR_EXC_SUM] |= env->fp_status.float_exception_flags << 1;
  95 +#endif
  96 + switch (env->fp_status.float_rounding_mode) {
  97 + case float_round_nearest_even:
  98 + T0 |= 2ULL << 58;
  99 + break;
  100 + case float_round_down:
  101 + T0 |= 1ULL << 58;
  102 + break;
  103 + case float_round_up:
  104 + T0 |= 3ULL << 58;
  105 + break;
  106 + case float_round_to_zero:
  107 + break;
  108 + }
  109 +}
  110 +
  111 +void helper_store_fpcr (void)
  112 +{
  113 +#ifdef CONFIG_SOFTFLOAT
  114 + set_float_exception_flags((T0 >> 52) & 0x3F, &FP_STATUS);
  115 +#endif
  116 + switch ((T0 >> 58) & 3) {
  117 + case 0:
  118 + set_float_rounding_mode(float_round_to_zero, &FP_STATUS);
  119 + break;
  120 + case 1:
  121 + set_float_rounding_mode(float_round_down, &FP_STATUS);
  122 + break;
  123 + case 2:
  124 + set_float_rounding_mode(float_round_nearest_even, &FP_STATUS);
  125 + break;
  126 + case 3:
  127 + set_float_rounding_mode(float_round_up, &FP_STATUS);
  128 + break;
  129 + }
  130 +}
  131 +
  132 +void helper_load_irf (void)
  133 +{
  134 + /* XXX: TODO */
  135 + T0 = 0;
  136 +}
  137 +
  138 +void helper_set_irf (void)
  139 +{
  140 + /* XXX: TODO */
  141 +}
  142 +
  143 +void helper_clear_irf (void)
  144 +{
  145 + /* XXX: TODO */
  146 +}
  147 +
  148 +void helper_addqv (void)
  149 +{
  150 + T2 = T0;
  151 + T0 += T1;
  152 + if (unlikely((T2 ^ T1 ^ (-1ULL)) & (T2 ^ T0) & (1ULL << 63))) {
  153 + helper_excp(EXCP_ARITH, EXCP_ARITH_OVERFLOW);
  154 + }
  155 +}
  156 +
  157 +void helper_addlv (void)
  158 +{
  159 + T2 = T0;
  160 + T0 = (uint32_t)(T0 + T1);
  161 + if (unlikely((T2 ^ T1 ^ (-1UL)) & (T2 ^ T0) & (1UL << 31))) {
  162 + helper_excp(EXCP_ARITH, EXCP_ARITH_OVERFLOW);
  163 + }
  164 +}
  165 +
  166 +void helper_subqv (void)
  167 +{
  168 + T2 = T0;
  169 + T0 -= T1;
  170 + if (unlikely(((~T2) ^ T0 ^ (-1ULL)) & ((~T2) ^ T1) & (1ULL << 63))) {
  171 + helper_excp(EXCP_ARITH, EXCP_ARITH_OVERFLOW);
  172 + }
  173 +}
  174 +
  175 +void helper_sublv (void)
  176 +{
  177 + T2 = T0;
  178 + T0 = (uint32_t)(T0 - T1);
  179 + if (unlikely(((~T2) ^ T0 ^ (-1UL)) & ((~T2) ^ T1) & (1UL << 31))) {
  180 + helper_excp(EXCP_ARITH, EXCP_ARITH_OVERFLOW);
  181 + }
  182 +}
  183 +
  184 +void helper_mullv (void)
  185 +{
  186 + int64_t res = (int64_t)T0 * (int64_t)T1;
  187 +
  188 + if (unlikely((int32_t)res != res)) {
  189 + helper_excp(EXCP_ARITH, EXCP_ARITH_OVERFLOW);
  190 + }
  191 + T0 = (int64_t)((int32_t)res);
  192 +}
  193 +
  194 +void helper_mulqv ()
  195 +{
  196 + uint64_t res, tmp0, tmp1;
  197 +
  198 + res = (T0 >> 32) * (T1 >> 32);
  199 + tmp0 = ((T0 & 0xFFFFFFFF) * (T1 >> 32)) +
  200 + ((T0 >> 32) * (T1 & 0xFFFFFFFF));
  201 + tmp1 = (T0 & 0xFFFFFFFF) * (T1 & 0xFFFFFFFF);
  202 + tmp0 += tmp1 >> 32;
  203 + res += tmp0 >> 32;
  204 + T0 *= T1;
  205 + if (unlikely(res != 0)) {
  206 + helper_excp(EXCP_ARITH, EXCP_ARITH_OVERFLOW);
  207 + }
  208 +}
  209 +
  210 +void helper_umulh (void)
  211 +{
  212 + uint64_t tmp0, tmp1;
  213 +
  214 + tmp0 = ((T0 & 0xFFFFFFFF) * (T1 >> 32)) +
  215 + ((T0 >> 32) * (T1 & 0xFFFFFFFF));
  216 + tmp1 = (T0 & 0xFFFFFFFF) * (T1 & 0xFFFFFFFF);
  217 + tmp0 += tmp1 >> 32;
  218 + T0 = (T0 >> 32) * (T0 >> 32);
  219 + T0 += tmp0 >> 32;
  220 +}
  221 +
  222 +void helper_ctpop (void)
  223 +{
  224 + int n;
  225 +
  226 + for (n = 0; T0 != 0; n++)
  227 + T0 = T0 ^ (T0 - 1);
  228 + T0 = n;
  229 +}
  230 +
  231 +void helper_ctlz (void)
  232 +{
  233 + uint32_t op32;
  234 + int n;
  235 +
  236 + n = 0;
  237 + if (!(T0 & 0xFFFFFFFF00000000ULL)) {
  238 + n += 32;
  239 + T0 <<= 32;
  240 + }
  241 + /* Make it easier for 32 bits hosts */
  242 + op32 = T0 >> 32;
  243 + if (!(op32 & 0xFFFF0000UL)) {
  244 + n += 16;
  245 + op32 <<= 16;
  246 + }
  247 + if (!(op32 & 0xFF000000UL)) {
  248 + n += 8;
  249 + op32 <<= 8;
  250 + }
  251 + if (!(op32 & 0xF0000000UL)) {
  252 + n += 4;
  253 + op32 <<= 4;
  254 + }
  255 + if (!(op32 & 0xC0000000UL)) {
  256 + n += 2;
  257 + op32 <<= 2;
  258 + }
  259 + if (!(op32 & 0x80000000UL)) {
  260 + n++;
  261 + op32 <<= 1;
  262 + }
  263 + if (!(op32 & 0x80000000UL)) {
  264 + n++;
  265 + }
  266 + T0 = n;
  267 +}
  268 +
  269 +void helper_cttz (void)
  270 +{
  271 + uint32_t op32;
  272 + int n;
  273 +
  274 + n = 0;
  275 + if (!(T0 & 0x00000000FFFFFFFFULL)) {
  276 + n += 32;
  277 + T0 >>= 32;
  278 + }
  279 + /* Make it easier for 32 bits hosts */
  280 + op32 = T0;
  281 + if (!(op32 & 0x0000FFFFUL)) {
  282 + n += 16;
  283 + op32 >>= 16;
  284 + }
  285 + if (!(op32 & 0x000000FFUL)) {
  286 + n += 8;
  287 + op32 >>= 8;
  288 + }
  289 + if (!(op32 & 0x0000000FUL)) {
  290 + n += 4;
  291 + op32 >>= 4;
  292 + }
  293 + if (!(op32 & 0x00000003UL)) {
  294 + n += 2;
  295 + op32 >>= 2;
  296 + }
  297 + if (!(op32 & 0x00000001UL)) {
  298 + n++;
  299 + op32 >>= 1;
  300 + }
  301 + if (!(op32 & 0x00000001UL)) {
  302 + n++;
  303 + }
  304 + T0 = n;
  305 +}
  306 +
  307 +static inline uint64_t byte_zap (uint64_t op, uint8_t mskb)
  308 +{
  309 + uint64_t mask;
  310 +
  311 + mask = 0;
  312 + mask |= ((mskb >> 0) & 1) * 0x00000000000000FFULL;
  313 + mask |= ((mskb >> 1) & 1) * 0x000000000000FF00ULL;
  314 + mask |= ((mskb >> 2) & 1) * 0x0000000000FF0000ULL;
  315 + mask |= ((mskb >> 3) & 1) * 0x00000000FF000000ULL;
  316 + mask |= ((mskb >> 4) & 1) * 0x000000FF00000000ULL;
  317 + mask |= ((mskb >> 5) & 1) * 0x0000FF0000000000ULL;
  318 + mask |= ((mskb >> 6) & 1) * 0x00FF000000000000ULL;
  319 + mask |= ((mskb >> 7) & 1) * 0xFF00000000000000ULL;
  320 +
  321 + return op & ~mask;
  322 +}
  323 +
  324 +void helper_mskbl (void)
  325 +{
  326 + T0 = byte_zap(T0, 0x01 << (T1 & 7));
  327 +}
  328 +
  329 +void helper_extbl (void)
  330 +{
  331 + T0 >>= (T1 & 7) * 8;
  332 + T0 = byte_zap(T0, 0xFE);
  333 +}
  334 +
  335 +void helper_insbl (void)
  336 +{
  337 + T0 <<= (T1 & 7) * 8;
  338 + T0 = byte_zap(T0, ~(0x01 << (T1 & 7)));
  339 +}
  340 +
  341 +void helper_mskwl (void)
  342 +{
  343 + T0 = byte_zap(T0, 0x03 << (T1 & 7));
  344 +}
  345 +
  346 +void helper_extwl (void)
  347 +{
  348 + T0 >>= (T1 & 7) * 8;
  349 + T0 = byte_zap(T0, 0xFC);
  350 +}
  351 +
  352 +void helper_inswl (void)
  353 +{
  354 + T0 <<= (T1 & 7) * 8;
  355 + T0 = byte_zap(T0, ~(0x03 << (T1 & 7)));
  356 +}
  357 +
  358 +void helper_mskll (void)
  359 +{
  360 + T0 = byte_zap(T0, 0x0F << (T1 & 7));
  361 +}
  362 +
  363 +void helper_extll (void)
  364 +{
  365 + T0 >>= (T1 & 7) * 8;
  366 + T0 = byte_zap(T0, 0xF0);
  367 +}
  368 +
  369 +void helper_insll (void)
  370 +{
  371 + T0 <<= (T1 & 7) * 8;
  372 + T0 = byte_zap(T0, ~(0x0F << (T1 & 7)));
  373 +}
  374 +
  375 +void helper_zap (void)
  376 +{
  377 + T0 = byte_zap(T0, T1);
  378 +}
  379 +
  380 +void helper_zapnot (void)
  381 +{
  382 + T0 = byte_zap(T0, ~T1);
  383 +}
  384 +
  385 +void helper_mskql (void)
  386 +{
  387 + T0 = byte_zap(T0, 0xFF << (T1 & 7));
  388 +}
  389 +
  390 +void helper_extql (void)
  391 +{
  392 + T0 >>= (T1 & 7) * 8;
  393 + T0 = byte_zap(T0, 0x00);
  394 +}
  395 +
  396 +void helper_insql (void)
  397 +{
  398 + T0 <<= (T1 & 7) * 8;
  399 + T0 = byte_zap(T0, ~(0xFF << (T1 & 7)));
  400 +}
  401 +
  402 +void helper_mskwh (void)
  403 +{
  404 + T0 = byte_zap(T0, (0x03 << (T1 & 7)) >> 8);
  405 +}
  406 +
  407 +void helper_inswh (void)
  408 +{
  409 + T0 >>= 64 - ((T1 & 7) * 8);
  410 + T0 = byte_zap(T0, ~((0x03 << (T1 & 7)) >> 8));
  411 +}
  412 +
  413 +void helper_extwh (void)
  414 +{
  415 + T0 <<= 64 - ((T1 & 7) * 8);
  416 + T0 = byte_zap(T0, ~0x07);
  417 +}
  418 +
  419 +void helper_msklh (void)
  420 +{
  421 + T0 = byte_zap(T0, (0x0F << (T1 & 7)) >> 8);
  422 +}
  423 +
  424 +void helper_inslh (void)
  425 +{
  426 + T0 >>= 64 - ((T1 & 7) * 8);
  427 + T0 = byte_zap(T0, ~((0x0F << (T1 & 7)) >> 8));
  428 +}
  429 +
  430 +void helper_extlh (void)
  431 +{
  432 + T0 <<= 64 - ((T1 & 7) * 8);
  433 + T0 = byte_zap(T0, ~0x0F);
  434 +}
  435 +
  436 +void helper_mskqh (void)
  437 +{
  438 + T0 = byte_zap(T0, (0xFF << (T1 & 7)) >> 8);
  439 +}
  440 +
  441 +void helper_insqh (void)
  442 +{
  443 + T0 >>= 64 - ((T1 & 7) * 8);
  444 + T0 = byte_zap(T0, ~((0xFF << (T1 & 7)) >> 8));
  445 +}
  446 +
  447 +void helper_extqh (void)
  448 +{
  449 + T0 <<= 64 - ((T1 & 7) * 8);
  450 + T0 = byte_zap(T0, 0x00);
  451 +}
  452 +
  453 +void helper_cmpbge (void)
  454 +{
  455 + uint8_t opa, opb, res;
  456 + int i;
  457 +
  458 + res = 0;
  459 + for (i = 0; i < 7; i++) {
  460 + opa = T0 >> (i * 8);
  461 + opb = T1 >> (i * 8);
  462 + if (opa >= opb)
  463 + res |= 1 << i;
  464 + }
  465 + T0 = res;
  466 +}
  467 +
  468 +void helper_cmov_fir (int freg)
  469 +{
  470 + if (FT0 != 0)
  471 + env->fir[freg] = FT1;
  472 +}
  473 +
  474 +void helper_sqrts (void)
  475 +{
  476 + FT0 = float32_sqrt(FT0, &FP_STATUS);
  477 +}
  478 +
  479 +void helper_cpys (void)
  480 +{
  481 + union {
  482 + double d;
  483 + uint64_t i;
  484 + } p, q, r;
  485 +
  486 + p.d = FT0;
  487 + q.d = FT1;
  488 + r.i = p.i & 0x8000000000000000ULL;
  489 + r.i |= q.i & ~0x8000000000000000ULL;
  490 + FT0 = r.d;
  491 +}
  492 +
  493 +void helper_cpysn (void)
  494 +{
  495 + union {
  496 + double d;
  497 + uint64_t i;
  498 + } p, q, r;
  499 +
  500 + p.d = FT0;
  501 + q.d = FT1;
  502 + r.i = (~p.i) & 0x8000000000000000ULL;
  503 + r.i |= q.i & ~0x8000000000000000ULL;
  504 + FT0 = r.d;
  505 +}
  506 +
  507 +void helper_cpyse (void)
  508 +{
  509 + union {
  510 + double d;
  511 + uint64_t i;
  512 + } p, q, r;
  513 +
  514 + p.d = FT0;
  515 + q.d = FT1;
  516 + r.i = p.i & 0xFFF0000000000000ULL;
  517 + r.i |= q.i & ~0xFFF0000000000000ULL;
  518 + FT0 = r.d;
  519 +}
  520 +
  521 +void helper_itofs (void)
  522 +{
  523 + union {
  524 + double d;
  525 + uint64_t i;
  526 + } p;
  527 +
  528 + p.d = FT0;
  529 + FT0 = int64_to_float32(p.i, &FP_STATUS);
  530 +}
  531 +
  532 +void helper_ftois (void)
  533 +{
  534 + union {
  535 + double d;
  536 + uint64_t i;
  537 + } p;
  538 +
  539 + p.i = float32_to_int64(FT0, &FP_STATUS);
  540 + FT0 = p.d;
  541 +}
  542 +
  543 +void helper_sqrtt (void)
  544 +{
  545 + FT0 = float64_sqrt(FT0, &FP_STATUS);
  546 +}
  547 +
  548 +void helper_cmptun (void)
  549 +{
  550 + union {
  551 + double d;
  552 + uint64_t i;
  553 + } p;
  554 +
  555 + p.i = 0;
  556 + if (float64_is_nan(FT0) || float64_is_nan(FT1))
  557 + p.i = 0x4000000000000000ULL;
  558 + FT0 = p.d;
  559 +}
  560 +
  561 +void helper_cmpteq (void)
  562 +{
  563 + union {
  564 + double d;
  565 + uint64_t i;
  566 + } p;
  567 +
  568 + p.i = 0;
  569 + if (float64_eq(FT0, FT1, &FP_STATUS))
  570 + p.i = 0x4000000000000000ULL;
  571 + FT0 = p.d;
  572 +}
  573 +
  574 +void helper_cmptle (void)
  575 +{
  576 + union {
  577 + double d;
  578 + uint64_t i;
  579 + } p;
  580 +
  581 + p.i = 0;
  582 + if (float64_le(FT0, FT1, &FP_STATUS))
  583 + p.i = 0x4000000000000000ULL;
  584 + FT0 = p.d;
  585 +}
  586 +
  587 +void helper_cmptlt (void)
  588 +{
  589 + union {
  590 + double d;
  591 + uint64_t i;
  592 + } p;
  593 +
  594 + p.i = 0;
  595 + if (float64_lt(FT0, FT1, &FP_STATUS))
  596 + p.i = 0x4000000000000000ULL;
  597 + FT0 = p.d;
  598 +}
  599 +
  600 +void helper_itoft (void)
  601 +{
  602 + union {
  603 + double d;
  604 + uint64_t i;
  605 + } p;
  606 +
  607 + p.d = FT0;
  608 + FT0 = int64_to_float64(p.i, &FP_STATUS);
  609 +}
  610 +
  611 +void helper_ftoit (void)
  612 +{
  613 + union {
  614 + double d;
  615 + uint64_t i;
  616 + } p;
  617 +
  618 + p.i = float64_to_int64(FT0, &FP_STATUS);
  619 + FT0 = p.d;
  620 +}
  621 +
  622 +static int vaxf_is_valid (float ff)
  623 +{
  624 + union {
  625 + float f;
  626 + uint32_t i;
  627 + } p;
  628 + uint32_t exp, mant;
  629 +
  630 + p.f = ff;
  631 + exp = (p.i >> 23) & 0xFF;
  632 + mant = p.i & 0x007FFFFF;
  633 + if (exp == 0 && ((p.i & 0x80000000) || mant != 0)) {
  634 + /* Reserved operands / Dirty zero */
  635 + return 0;
  636 + }
  637 +
  638 + return 1;
  639 +}
  640 +
  641 +static float vaxf_to_ieee32 (float ff)
  642 +{
  643 + union {
  644 + float f;
  645 + uint32_t i;
  646 + } p;
  647 + uint32_t exp;
  648 +
  649 + p.f = ff;
  650 + exp = (p.i >> 23) & 0xFF;
  651 + if (exp < 3) {
  652 + /* Underflow */
  653 + p.f = 0.0;
  654 + } else {
  655 + p.f *= 0.25;
  656 + }
  657 +
  658 + return p.f;
  659 +}
  660 +
  661 +static float ieee32_to_vaxf (float fi)
  662 +{
  663 + union {
  664 + float f;
  665 + uint32_t i;
  666 + } p;
  667 + uint32_t exp, mant;
  668 +
  669 + p.f = fi;
  670 + exp = (p.i >> 23) & 0xFF;
  671 + mant = p.i & 0x007FFFFF;
  672 + if (exp == 255) {
  673 + /* NaN or infinity */
  674 + p.i = 1;
  675 + } else if (exp == 0) {
  676 + if (mant == 0) {
  677 + /* Zero */
  678 + p.i = 0;
  679 + } else {
  680 + /* Denormalized */
  681 + p.f *= 2.0;
  682 + }
  683 + } else {
  684 + if (exp >= 253) {
  685 + /* Overflow */
  686 + p.i = 1;
  687 + } else {
  688 + p.f *= 4.0;
  689 + }
  690 + }
  691 +
  692 + return p.f;
  693 +}
  694 +
  695 +void helper_addf (void)
  696 +{
  697 + float ft0, ft1, ft2;
  698 +
  699 + if (!vaxf_is_valid(FT0) || !vaxf_is_valid(FT1)) {
  700 + /* XXX: TODO */
  701 + }
  702 + ft0 = vaxf_to_ieee32(FT0);
  703 + ft1 = vaxf_to_ieee32(FT1);
  704 + ft2 = float32_add(ft0, ft1, &FP_STATUS);
  705 + FT0 = ieee32_to_vaxf(ft2);
  706 +}
  707 +
  708 +void helper_subf (void)
  709 +{
  710 + float ft0, ft1, ft2;
  711 +
  712 + if (!vaxf_is_valid(FT0) || !vaxf_is_valid(FT1)) {
  713 + /* XXX: TODO */
  714 + }
  715 + ft0 = vaxf_to_ieee32(FT0);
  716 + ft1 = vaxf_to_ieee32(FT1);
  717 + ft2 = float32_sub(ft0, ft1, &FP_STATUS);
  718 + FT0 = ieee32_to_vaxf(ft2);
  719 +}
  720 +
  721 +void helper_mulf (void)
  722 +{
  723 + float ft0, ft1, ft2;
  724 +
  725 + if (!vaxf_is_valid(FT0) || !vaxf_is_valid(FT1)) {
  726 + /* XXX: TODO */
  727 + }
  728 + ft0 = vaxf_to_ieee32(FT0);
  729 + ft1 = vaxf_to_ieee32(FT1);
  730 + ft2 = float32_mul(ft0, ft1, &FP_STATUS);
  731 + FT0 = ieee32_to_vaxf(ft2);
  732 +}
  733 +
  734 +void helper_divf (void)
  735 +{
  736 + float ft0, ft1, ft2;
  737 +
  738 + if (!vaxf_is_valid(FT0) || !vaxf_is_valid(FT1)) {
  739 + /* XXX: TODO */
  740 + }
  741 + ft0 = vaxf_to_ieee32(FT0);
  742 + ft1 = vaxf_to_ieee32(FT1);
  743 + ft2 = float32_div(ft0, ft1, &FP_STATUS);
  744 + FT0 = ieee32_to_vaxf(ft2);
  745 +}
  746 +
  747 +void helper_sqrtf (void)
  748 +{
  749 + float ft0, ft1;
  750 +
  751 + if (!vaxf_is_valid(FT0) || !vaxf_is_valid(FT1)) {
  752 + /* XXX: TODO */
  753 + }
  754 + ft0 = vaxf_to_ieee32(FT0);
  755 + ft1 = float32_sqrt(ft0, &FP_STATUS);
  756 + FT0 = ieee32_to_vaxf(ft1);
  757 +}
  758 +
  759 +void helper_itoff (void)
  760 +{
  761 + /* XXX: TODO */
  762 +}
  763 +
  764 +static int vaxg_is_valid (double ff)
  765 +{
  766 + union {
  767 + double f;
  768 + uint64_t i;
  769 + } p;
  770 + uint64_t exp, mant;
  771 +
  772 + p.f = ff;
  773 + exp = (p.i >> 52) & 0x7FF;
  774 + mant = p.i & 0x000FFFFFFFFFFFFFULL;
  775 + if (exp == 0 && ((p.i & 0x8000000000000000ULL) || mant != 0)) {
  776 + /* Reserved operands / Dirty zero */
  777 + return 0;
  778 + }
  779 +
  780 + return 1;
  781 +}
  782 +
  783 +static double vaxg_to_ieee64 (double fg)
  784 +{
  785 + union {
  786 + double f;
  787 + uint64_t i;
  788 + } p;
  789 + uint32_t exp;
  790 +
  791 + p.f = fg;
  792 + exp = (p.i >> 52) & 0x7FF;
  793 + if (exp < 3) {
  794 + /* Underflow */
  795 + p.f = 0.0;
  796 + } else {
  797 + p.f *= 0.25;
  798 + }
  799 +
  800 + return p.f;
  801 +}
  802 +
  803 +static double ieee64_to_vaxg (double fi)
  804 +{
  805 + union {
  806 + double f;
  807 + uint64_t i;
  808 + } p;
  809 + uint64_t mant;
  810 + uint32_t exp;
  811 +
  812 + p.f = fi;
  813 + exp = (p.i >> 52) & 0x7FF;
  814 + mant = p.i & 0x000FFFFFFFFFFFFFULL;
  815 + if (exp == 255) {
  816 + /* NaN or infinity */
  817 + p.i = 1; /* VAX dirty zero */
  818 + } else if (exp == 0) {
  819 + if (mant == 0) {
  820 + /* Zero */
  821 + p.i = 0;
  822 + } else {
  823 + /* Denormalized */
  824 + p.f *= 2.0;
  825 + }
  826 + } else {
  827 + if (exp >= 2045) {
  828 + /* Overflow */
  829 + p.i = 1; /* VAX dirty zero */
  830 + } else {
  831 + p.f *= 4.0;
  832 + }
  833 + }
  834 +
  835 + return p.f;
  836 +}
  837 +
  838 +void helper_addg (void)
  839 +{
  840 + double ft0, ft1, ft2;
  841 +
  842 + if (!vaxg_is_valid(FT0) || !vaxg_is_valid(FT1)) {
  843 + /* XXX: TODO */
  844 + }
  845 + ft0 = vaxg_to_ieee64(FT0);
  846 + ft1 = vaxg_to_ieee64(FT1);
  847 + ft2 = float64_add(ft0, ft1, &FP_STATUS);
  848 + FT0 = ieee64_to_vaxg(ft2);
  849 +}
  850 +
  851 +void helper_subg (void)
  852 +{
  853 + double ft0, ft1, ft2;
  854 +
  855 + if (!vaxg_is_valid(FT0) || !vaxg_is_valid(FT1)) {
  856 + /* XXX: TODO */
  857 + }
  858 + ft0 = vaxg_to_ieee64(FT0);
  859 + ft1 = vaxg_to_ieee64(FT1);
  860 + ft2 = float64_sub(ft0, ft1, &FP_STATUS);
  861 + FT0 = ieee64_to_vaxg(ft2);
  862 +}
  863 +
  864 +void helper_mulg (void)
  865 +{
  866 + double ft0, ft1, ft2;
  867 +
  868 + if (!vaxg_is_valid(FT0) || !vaxg_is_valid(FT1)) {
  869 + /* XXX: TODO */
  870 + }
  871 + ft0 = vaxg_to_ieee64(FT0);
  872 + ft1 = vaxg_to_ieee64(FT1);
  873 + ft2 = float64_mul(ft0, ft1, &FP_STATUS);
  874 + FT0 = ieee64_to_vaxg(ft2);
  875 +}
  876 +
  877 +void helper_divg (void)
  878 +{
  879 + double ft0, ft1, ft2;
  880 +
  881 + if (!vaxg_is_valid(FT0) || !vaxg_is_valid(FT1)) {
  882 + /* XXX: TODO */
  883 + }
  884 + ft0 = vaxg_to_ieee64(FT0);
  885 + ft1 = vaxg_to_ieee64(FT1);
  886 + ft2 = float64_div(ft0, ft1, &FP_STATUS);
  887 + FT0 = ieee64_to_vaxg(ft2);
  888 +}
  889 +
  890 +void helper_sqrtg (void)
  891 +{
  892 + double ft0, ft1;
  893 +
  894 + if (!vaxg_is_valid(FT0) || !vaxg_is_valid(FT1)) {
  895 + /* XXX: TODO */
  896 + }
  897 + ft0 = vaxg_to_ieee64(FT0);
  898 + ft1 = float64_sqrt(ft0, &FP_STATUS);
  899 + FT0 = ieee64_to_vaxg(ft1);
  900 +}
  901 +
  902 +void helper_cmpgeq (void)
  903 +{
  904 + union {
  905 + double d;
  906 + uint64_t u;
  907 + } p;
  908 + double ft0, ft1;
  909 +
  910 + if (!vaxg_is_valid(FT0) || !vaxg_is_valid(FT1)) {
  911 + /* XXX: TODO */
  912 + }
  913 + ft0 = vaxg_to_ieee64(FT0);
  914 + ft1 = vaxg_to_ieee64(FT1);
  915 + p.u = 0;
  916 + if (float64_eq(ft0, ft1, &FP_STATUS))
  917 + p.u = 0x4000000000000000ULL;
  918 + FT0 = p.d;
  919 +}
  920 +
  921 +void helper_cmpglt (void)
  922 +{
  923 + union {
  924 + double d;
  925 + uint64_t u;
  926 + } p;
  927 + double ft0, ft1;
  928 +
  929 + if (!vaxg_is_valid(FT0) || !vaxg_is_valid(FT1)) {
  930 + /* XXX: TODO */
  931 + }
  932 + ft0 = vaxg_to_ieee64(FT0);
  933 + ft1 = vaxg_to_ieee64(FT1);
  934 + p.u = 0;
  935 + if (float64_lt(ft0, ft1, &FP_STATUS))
  936 + p.u = 0x4000000000000000ULL;
  937 + FT0 = p.d;
  938 +}
  939 +
  940 +void helper_cmpgle (void)
  941 +{
  942 + union {
  943 + double d;
  944 + uint64_t u;
  945 + } p;
  946 + double ft0, ft1;
  947 +
  948 + if (!vaxg_is_valid(FT0) || !vaxg_is_valid(FT1)) {
  949 + /* XXX: TODO */
  950 + }
  951 + ft0 = vaxg_to_ieee64(FT0);
  952 + ft1 = vaxg_to_ieee64(FT1);
  953 + p.u = 0;
  954 + if (float64_le(ft0, ft1, &FP_STATUS))
  955 + p.u = 0x4000000000000000ULL;
  956 + FT0 = p.d;
  957 +}
  958 +
  959 +void helper_cvtqs (void)
  960 +{
  961 + union {
  962 + double d;
  963 + uint64_t u;
  964 + } p;
  965 +
  966 + p.d = FT0;
  967 + FT0 = (float)p.u;
  968 +}
  969 +
  970 +void helper_cvttq (void)
  971 +{
  972 + union {
  973 + double d;
  974 + uint64_t u;
  975 + } p;
  976 +
  977 + p.u = FT0;
  978 + FT0 = p.d;
  979 +}
  980 +
  981 +void helper_cvtqt (void)
  982 +{
  983 + union {
  984 + double d;
  985 + uint64_t u;
  986 + } p;
  987 +
  988 + p.d = FT0;
  989 + FT0 = p.u;
  990 +}
  991 +
  992 +void helper_cvtqf (void)
  993 +{
  994 + union {
  995 + double d;
  996 + uint64_t u;
  997 + } p;
  998 +
  999 + p.d = FT0;
  1000 + FT0 = ieee32_to_vaxf(p.u);
  1001 +}
  1002 +
  1003 +void helper_cvtgf (void)
  1004 +{
  1005 + double ft0;
  1006 +
  1007 + ft0 = vaxg_to_ieee64(FT0);
  1008 + FT0 = ieee32_to_vaxf(ft0);
  1009 +}
  1010 +
  1011 +void helper_cvtgd (void)
  1012 +{
  1013 + /* XXX: TODO */
  1014 +}
  1015 +
  1016 +void helper_cvtgq (void)
  1017 +{
  1018 + union {
  1019 + double d;
  1020 + uint64_t u;
  1021 + } p;
  1022 +
  1023 + p.u = vaxg_to_ieee64(FT0);
  1024 + FT0 = p.d;
  1025 +}
  1026 +
  1027 +void helper_cvtqg (void)
  1028 +{
  1029 + union {
  1030 + double d;
  1031 + uint64_t u;
  1032 + } p;
  1033 +
  1034 + p.d = FT0;
  1035 + FT0 = ieee64_to_vaxg(p.u);
  1036 +}
  1037 +
  1038 +void helper_cvtdg (void)
  1039 +{
  1040 + /* XXX: TODO */
  1041 +}
  1042 +
  1043 +void helper_cvtlq (void)
  1044 +{
  1045 + union {
  1046 + double d;
  1047 + uint64_t u;
  1048 + } p, q;
  1049 +
  1050 + p.d = FT0;
  1051 + q.u = (p.u >> 29) & 0x3FFFFFFF;
  1052 + q.u |= (p.u >> 32);
  1053 + q.u = (int64_t)((int32_t)q.u);
  1054 + FT0 = q.d;
  1055 +}
  1056 +
  1057 +static inline void __helper_cvtql (int s, int v)
  1058 +{
  1059 + union {
  1060 + double d;
  1061 + uint64_t u;
  1062 + } p, q;
  1063 +
  1064 + p.d = FT0;
  1065 + q.u = ((uint64_t)(p.u & 0xC0000000)) << 32;
  1066 + q.u |= ((uint64_t)(p.u & 0x7FFFFFFF)) << 29;
  1067 + FT0 = q.d;
  1068 + if (v && (int64_t)((int32_t)p.u) != (int64_t)p.u) {
  1069 + helper_excp(EXCP_ARITH, EXCP_ARITH_OVERFLOW);
  1070 + }
  1071 + if (s) {
  1072 + /* TODO */
  1073 + }
  1074 +}
  1075 +
  1076 +void helper_cvtql (void)
  1077 +{
  1078 + __helper_cvtql(0, 0);
  1079 +}
  1080 +
  1081 +void helper_cvtqlv (void)
  1082 +{
  1083 + __helper_cvtql(0, 1);
  1084 +}
  1085 +
  1086 +void helper_cvtqlsv (void)
  1087 +{
  1088 + __helper_cvtql(1, 1);
  1089 +}
  1090 +
  1091 +void helper_cmpfeq (void)
  1092 +{
  1093 + if (float64_eq(FT0, FT1, &FP_STATUS))
  1094 + T0 = 1;
  1095 + else
  1096 + T0 = 0;
  1097 +}
  1098 +
  1099 +void helper_cmpfne (void)
  1100 +{
  1101 + if (float64_eq(FT0, FT1, &FP_STATUS))
  1102 + T0 = 0;
  1103 + else
  1104 + T0 = 1;
  1105 +}
  1106 +
  1107 +void helper_cmpflt (void)
  1108 +{
  1109 + if (float64_lt(FT0, FT1, &FP_STATUS))
  1110 + T0 = 1;
  1111 + else
  1112 + T0 = 0;
  1113 +}
  1114 +
  1115 +void helper_cmpfle (void)
  1116 +{
  1117 + if (float64_lt(FT0, FT1, &FP_STATUS))
  1118 + T0 = 1;
  1119 + else
  1120 + T0 = 0;
  1121 +}
  1122 +
  1123 +void helper_cmpfgt (void)
  1124 +{
  1125 + if (float64_le(FT0, FT1, &FP_STATUS))
  1126 + T0 = 0;
  1127 + else
  1128 + T0 = 1;
  1129 +}
  1130 +
  1131 +void helper_cmpfge (void)
  1132 +{
  1133 + if (float64_lt(FT0, FT1, &FP_STATUS))
  1134 + T0 = 0;
  1135 + else
  1136 + T0 = 1;
  1137 +}
  1138 +
  1139 +#if !defined (CONFIG_USER_ONLY)
  1140 +void helper_mfpr (int iprn)
  1141 +{
  1142 + uint64_t val;
  1143 +
  1144 + if (cpu_alpha_mfpr(env, iprn, &val) == 0)
  1145 + T0 = val;
  1146 +}
  1147 +
  1148 +void helper_mtpr (int iprn)
  1149 +{
  1150 + cpu_alpha_mtpr(env, iprn, T0, NULL);
  1151 +}
  1152 +#endif
  1153 +
  1154 +/*****************************************************************************/
  1155 +/* Softmmu support */
  1156 +#if !defined (CONFIG_USER_ONLY)
  1157 +
  1158 +#define GETPC() (__builtin_return_address(0))
  1159 +
  1160 +/* XXX: the two following helpers are pure hacks.
  1161 + * Hopefully, we emulate the PALcode, then we should never see
  1162 + * HW_LD / HW_ST instructions.
  1163 + */
  1164 +void helper_ld_phys_to_virt (void)
  1165 +{
  1166 + uint64_t tlb_addr, physaddr;
  1167 + int index, is_user;
  1168 + void *retaddr;
  1169 +
  1170 + is_user = (env->ps >> 3) & 3;
  1171 + index = (T0 >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
  1172 + redo:
  1173 + tlb_addr = env->tlb_table[is_user][index].addr_read;
  1174 + if ((T0 & TARGET_PAGE_MASK) ==
  1175 + (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
  1176 + physaddr = T0 + env->tlb_table[is_user][index].addend;
  1177 + } else {
  1178 + /* the page is not in the TLB : fill it */
  1179 + retaddr = GETPC();
  1180 + tlb_fill(T0, 0, is_user, retaddr);
  1181 + goto redo;
  1182 + }
  1183 + T0 = physaddr;
  1184 +}
  1185 +
  1186 +void helper_st_phys_to_virt (void)
  1187 +{
  1188 + uint64_t tlb_addr, physaddr;
  1189 + int index, is_user;
  1190 + void *retaddr;
  1191 +
  1192 + is_user = (env->ps >> 3) & 3;
  1193 + index = (T0 >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
  1194 + redo:
  1195 + tlb_addr = env->tlb_table[is_user][index].addr_write;
  1196 + if ((T0 & TARGET_PAGE_MASK) ==
  1197 + (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
  1198 + physaddr = T0 + env->tlb_table[is_user][index].addend;
  1199 + } else {
  1200 + /* the page is not in the TLB : fill it */
  1201 + retaddr = GETPC();
  1202 + tlb_fill(T0, 1, is_user, retaddr);
  1203 + goto redo;
  1204 + }
  1205 + T0 = physaddr;
  1206 +}
  1207 +
  1208 +#define MMUSUFFIX _mmu
  1209 +
  1210 +#define SHIFT 0
  1211 +#include "softmmu_template.h"
  1212 +
  1213 +#define SHIFT 1
  1214 +#include "softmmu_template.h"
  1215 +
  1216 +#define SHIFT 2
  1217 +#include "softmmu_template.h"
  1218 +
  1219 +#define SHIFT 3
  1220 +#include "softmmu_template.h"
  1221 +
  1222 +/* try to fill the TLB and return an exception if error. If retaddr is
  1223 + NULL, it means that the function was called in C code (i.e. not
  1224 + from generated code or from helper.c) */
  1225 +/* XXX: fix it to restore all registers */
  1226 +void tlb_fill (target_ulong addr, int is_write, int is_user, void *retaddr)
  1227 +{
  1228 + TranslationBlock *tb;
  1229 + CPUState *saved_env;
  1230 + target_phys_addr_t pc;
  1231 + int ret;
  1232 +
  1233 + /* XXX: hack to restore env in all cases, even if not called from
  1234 + generated code */
  1235 + saved_env = env;
  1236 + env = cpu_single_env;
  1237 + ret = cpu_alpha_handle_mmu_fault(env, addr, is_write, is_user, 1);
  1238 + if (!likely(ret == 0)) {
  1239 + if (likely(retaddr)) {
  1240 + /* now we have a real cpu fault */
  1241 + pc = (target_phys_addr_t)retaddr;
  1242 + tb = tb_find_pc(pc);
  1243 + if (likely(tb)) {
  1244 + /* the PC is inside the translated code. It means that we have
  1245 + a virtual CPU fault */
  1246 + cpu_restore_state(tb, env, pc, NULL);
  1247 + }
  1248 + }
  1249 + /* Exception index and error code are already set */
  1250 + cpu_loop_exit();
  1251 + }
  1252 + env = saved_env;
  1253 +}
  1254 +
  1255 +#endif
target-alpha/op_helper.h 0 → 100644
  1 +/*
  2 + * Alpha emulation cpu micro-operations helpers definitions for qemu.
  3 + *
  4 + * Copyright (c) 2007 Jocelyn Mayer
  5 + *
  6 + * This library is free software; you can redistribute it and/or
  7 + * modify it under the terms of the GNU Lesser General Public
  8 + * License as published by the Free Software Foundation; either
  9 + * version 2 of the License, or (at your option) any later version.
  10 + *
  11 + * This library is distributed in the hope that it will be useful,
  12 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14 + * Lesser General Public License for more details.
  15 + *
  16 + * You should have received a copy of the GNU Lesser General Public
  17 + * License along with this library; if not, write to the Free Software
  18 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  19 + */
  20 +
  21 +void helper_call_pal (uint32_t palcode);
  22 +void helper_excp (uint32_t excp, uint32_t error);
  23 +void helper_amask (void);
  24 +void helper_load_pcc (void);
  25 +void helper_load_implver (void);
  26 +void helper_load_fpcr (void);
  27 +void helper_store_fpcr (void);
  28 +void helper_load_irf (void);
  29 +void helper_set_irf (void);
  30 +void helper_clear_irf (void);
  31 +void helper_addqv (void);
  32 +void helper_addlv (void);
  33 +void helper_subqv (void);
  34 +void helper_sublv (void);
  35 +void helper_mullv (void);
  36 +void helper_mulqv (void);
  37 +void helper_umulh (void);
  38 +void helper_ctpop (void);
  39 +void helper_ctlz (void);
  40 +void helper_cttz (void);
  41 +void helper_mskbl (void);
  42 +void helper_extbl (void);
  43 +void helper_insbl (void);
  44 +void helper_mskwl (void);
  45 +void helper_extwl (void);
  46 +void helper_inswl (void);
  47 +void helper_mskll (void);
  48 +void helper_extll (void);
  49 +void helper_insll (void);
  50 +void helper_zap (void);
  51 +void helper_zapnot (void);
  52 +void helper_mskql (void);
  53 +void helper_extql (void);
  54 +void helper_insql (void);
  55 +void helper_mskwh (void);
  56 +void helper_inswh (void);
  57 +void helper_extwh (void);
  58 +void helper_msklh (void);
  59 +void helper_inslh (void);
  60 +void helper_extlh (void);
  61 +void helper_mskqh (void);
  62 +void helper_insqh (void);
  63 +void helper_extqh (void);
  64 +void helper_cmpbge (void);
  65 +void helper_cmov_fir (int freg);
  66 +
  67 +double helper_ldff_raw (target_ulong ea);
  68 +void helper_stff_raw (target_ulong ea, double op);
  69 +double helper_ldfg_raw (target_ulong ea);
  70 +void helper_stfg_raw (target_ulong ea, double op);
  71 +#if !defined(CONFIG_USER_ONLY)
  72 +double helper_ldff_user (target_ulong ea);
  73 +void helper_stff_user (target_ulong ea, double op);
  74 +double helper_ldff_kernel (target_ulong ea);
  75 +void helper_stff_kernel (target_ulong ea, double op);
  76 +double helper_ldff_data (target_ulong ea);
  77 +void helper_stff_data (target_ulong ea, double op);
  78 +double helper_ldfg_user (target_ulong ea);
  79 +void helper_stfg_user (target_ulong ea, double op);
  80 +double helper_ldfg_kernel (target_ulong ea);
  81 +void helper_stfg_kernel (target_ulong ea, double op);
  82 +double helper_ldfg_data (target_ulong ea);
  83 +void helper_stfg_data (target_ulong ea, double op);
  84 +#endif
  85 +
  86 +void helper_sqrts (void);
  87 +void helper_cpys (void);
  88 +void helper_cpysn (void);
  89 +void helper_cpyse (void);
  90 +void helper_itofs (void);
  91 +void helper_ftois (void);
  92 +
  93 +void helper_sqrtt (void);
  94 +void helper_cmptun (void);
  95 +void helper_cmpteq (void);
  96 +void helper_cmptle (void);
  97 +void helper_cmptlt (void);
  98 +void helper_itoft (void);
  99 +void helper_ftoit (void);
  100 +
  101 +void helper_addf (void);
  102 +void helper_subf (void);
  103 +void helper_mulf (void);
  104 +void helper_divf (void);
  105 +void helper_sqrtf (void);
  106 +void helper_cmpfeq (void);
  107 +void helper_cmpfne (void);
  108 +void helper_cmpflt (void);
  109 +void helper_cmpfle (void);
  110 +void helper_cmpfgt (void);
  111 +void helper_cmpfge (void);
  112 +void helper_itoff (void);
  113 +
  114 +void helper_addg (void);
  115 +void helper_subg (void);
  116 +void helper_mulg (void);
  117 +void helper_divg (void);
  118 +void helper_sqrtg (void);
  119 +void helper_cmpgeq (void);
  120 +void helper_cmpglt (void);
  121 +void helper_cmpgle (void);
  122 +
  123 +void helper_cvtqs (void);
  124 +void helper_cvttq (void);
  125 +void helper_cvtqt (void);
  126 +void helper_cvtqf (void);
  127 +void helper_cvtgf (void);
  128 +void helper_cvtgd (void);
  129 +void helper_cvtgq (void);
  130 +void helper_cvtqg (void);
  131 +void helper_cvtdg (void);
  132 +void helper_cvtlq (void);
  133 +void helper_cvtql (void);
  134 +void helper_cvtqlv (void);
  135 +void helper_cvtqlsv (void);
  136 +
  137 +void helper_mfpr (int iprn);
  138 +void helper_mtpr (int iprn);
  139 +void helper_ld_phys_to_virt (void);
  140 +void helper_st_phys_to_virt (void);
  141 +void helper_tb_flush (void);
target-alpha/op_helper_mem.h 0 → 100644
  1 +/*
  2 + * Alpha emulation cpu micro-operations helpers for memory accesses for qemu.
  3 + *
  4 + * Copyright (c) 2007 Jocelyn Mayer
  5 + *
  6 + * This library is free software; you can redistribute it and/or
  7 + * modify it under the terms of the GNU Lesser General Public
  8 + * License as published by the Free Software Foundation; either
  9 + * version 2 of the License, or (at your option) any later version.
  10 + *
  11 + * This library is distributed in the hope that it will be useful,
  12 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14 + * Lesser General Public License for more details.
  15 + *
  16 + * You should have received a copy of the GNU Lesser General Public
  17 + * License along with this library; if not, write to the Free Software
  18 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  19 + */
  20 +
  21 +/* XXX: TODO */
  22 +double glue(helper_ldff, MEMSUFFIX) (target_ulong ea)
  23 +{
  24 + return 0;
  25 +}
  26 +
  27 +void glue(helper_stff, MEMSUFFIX) (target_ulong ea, double op)
  28 +{
  29 +}
  30 +
  31 +double glue(helper_ldfg, MEMSUFFIX) (target_ulong ea)
  32 +{
  33 + return 0;
  34 +}
  35 +
  36 +void glue(helper_stfg, MEMSUFFIX) (target_ulong ea, double op)
  37 +{
  38 +}
  39 +
  40 +#undef MEMSUFFIX
target-alpha/op_mem.h 0 → 100644
  1 +/*
  2 + * Alpha emulation cpu micro-operations for memory accesses for qemu.
  3 + *
  4 + * Copyright (c) 2007 Jocelyn Mayer
  5 + *
  6 + * This library is free software; you can redistribute it and/or
  7 + * modify it under the terms of the GNU Lesser General Public
  8 + * License as published by the Free Software Foundation; either
  9 + * version 2 of the License, or (at your option) any later version.
  10 + *
  11 + * This library is distributed in the hope that it will be useful,
  12 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14 + * Lesser General Public License for more details.
  15 + *
  16 + * You should have received a copy of the GNU Lesser General Public
  17 + * License along with this library; if not, write to the Free Software
  18 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  19 + */
  20 +
  21 +#define DEBUG_MEM_ACCESSES
  22 +#if defined (DEBUG_MEM_ACCESSES)
  23 +void helper_print_mem_EA (target_ulong EA);
  24 +#define print_mem_EA(EA) do { helper_print_mem_EA(EA); } while (0)
  25 +#else
  26 +#define print_mem_EA(EA) do { } while (0)
  27 +#endif
  28 +
  29 +static inline uint32_t glue(ldl_l, MEMSUFFIX) (target_ulong EA)
  30 +{
  31 + env->lock = EA;
  32 +
  33 + return glue(ldl, MEMSUFFIX)(EA);
  34 +}
  35 +
  36 +static inline uint32_t glue(ldq_l, MEMSUFFIX) (target_ulong EA)
  37 +{
  38 + env->lock = EA;
  39 +
  40 + return glue(ldq, MEMSUFFIX)(EA);
  41 +}
  42 +
  43 +static inline void glue(stl_c, MEMSUFFIX) (target_ulong EA, uint32_t data)
  44 +{
  45 + if (EA == env->lock) {
  46 + glue(stl, MEMSUFFIX)(EA, data);
  47 + T0 = 0;
  48 + } else {
  49 + T0 = 1;
  50 + }
  51 + env->lock = -1;
  52 +}
  53 +
  54 +static inline void glue(stq_c, MEMSUFFIX) (target_ulong EA, uint64_t data)
  55 +{
  56 + if (EA == env->lock) {
  57 + glue(stq, MEMSUFFIX)(EA, data);
  58 + T0 = 0;
  59 + } else {
  60 + T0 = 1;
  61 + }
  62 + env->lock = -1;
  63 +}
  64 +
  65 +#define ALPHA_LD_OP(name, op) \
  66 +void OPPROTO glue(glue(op_ld, name), MEMSUFFIX) (void) \
  67 +{ \
  68 + print_mem_EA(T0); \
  69 + T1 = glue(op, MEMSUFFIX)(T0); \
  70 + RETURN(); \
  71 +}
  72 +
  73 +#define ALPHA_ST_OP(name, op) \
  74 +void OPPROTO glue(glue(op_st, name), MEMSUFFIX) (void) \
  75 +{ \
  76 + print_mem_EA(T0); \
  77 + glue(op, MEMSUFFIX)(T0, T1); \
  78 + RETURN(); \
  79 +}
  80 +
  81 +ALPHA_LD_OP(bu, ldub);
  82 +ALPHA_ST_OP(b, stb);
  83 +ALPHA_LD_OP(wu, lduw);
  84 +ALPHA_ST_OP(w, stw);
  85 +ALPHA_LD_OP(l, ldl);
  86 +ALPHA_ST_OP(l, stl);
  87 +ALPHA_LD_OP(q, ldq);
  88 +ALPHA_ST_OP(q, stq);
  89 +
  90 +ALPHA_LD_OP(q_u, ldq);
  91 +ALPHA_ST_OP(q_u, stq);
  92 +
  93 +ALPHA_LD_OP(l_l, ldl_l);
  94 +ALPHA_LD_OP(q_l, ldq_l);
  95 +ALPHA_ST_OP(l_c, stl_c);
  96 +ALPHA_ST_OP(q_c, stq_c);
  97 +
  98 +#define ALPHA_LDF_OP(name, op) \
  99 +void OPPROTO glue(glue(op_ld, name), MEMSUFFIX) (void) \
  100 +{ \
  101 + print_mem_EA(T0); \
  102 + FT1 = glue(op, MEMSUFFIX)(T0); \
  103 + RETURN(); \
  104 +}
  105 +
  106 +#define ALPHA_STF_OP(name, op) \
  107 +void OPPROTO glue(glue(op_st, name), MEMSUFFIX) (void) \
  108 +{ \
  109 + print_mem_EA(T0); \
  110 + glue(op, MEMSUFFIX)(T0, FT1); \
  111 + RETURN(); \
  112 +}
  113 +
  114 +ALPHA_LDF_OP(t, ldfq);
  115 +ALPHA_STF_OP(t, stfq);
  116 +ALPHA_LDF_OP(s, ldfl);
  117 +ALPHA_STF_OP(s, stfl);
  118 +
  119 +/* VAX floating point */
  120 +ALPHA_LDF_OP(f, helper_ldff);
  121 +ALPHA_STF_OP(f, helper_stff);
  122 +ALPHA_LDF_OP(g, helper_ldfg);
  123 +ALPHA_STF_OP(g, helper_stfg);
  124 +
  125 +#undef MEMSUFFIX
target-alpha/op_template.h 0 → 100644
  1 +/*
  2 + * Alpha emulation cpu micro-operations templates for qemu.
  3 + *
  4 + * Copyright (c) 2007 Jocelyn Mayer
  5 + *
  6 + * This library is free software; you can redistribute it and/or
  7 + * modify it under the terms of the GNU Lesser General Public
  8 + * License as published by the Free Software Foundation; either
  9 + * version 2 of the License, or (at your option) any later version.
  10 + *
  11 + * This library is distributed in the hope that it will be useful,
  12 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14 + * Lesser General Public License for more details.
  15 + *
  16 + * You should have received a copy of the GNU Lesser General Public
  17 + * License along with this library; if not, write to the Free Software
  18 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  19 + */
  20 +
  21 +/* Optimized constant loads */
  22 +#if REG < 3
  23 +void OPPROTO glue(op_reset_T, REG) (void)
  24 +{
  25 + glue(T, REG) = 0;
  26 + RETURN();
  27 +}
  28 +
  29 +void OPPROTO glue(op_reset_FT, REG) (void)
  30 +{
  31 + glue(FT, REG) = 0;
  32 + RETURN();
  33 +}
  34 +
  35 +/* XXX: This can be great on most RISC machines */
  36 +#if !defined(__i386__) && !defined(__x86_64__)
  37 +void OPPROTO glue(op_set_s16_T, REG) (void)
  38 +{
  39 + glue(T, REG) = (int16_t)PARAM(1);
  40 + RETURN();
  41 +}
  42 +
  43 +void OPPROTO glue(op_set_u16_T, REG) (void)
  44 +{
  45 + glue(T, REG) = (uint16_t)PARAM(1);
  46 + RETURN();
  47 +}
  48 +#endif
  49 +
  50 +void OPPROTO glue(op_set_s32_T, REG) (void)
  51 +{
  52 + glue(T, REG) = (int32_t)PARAM(1);
  53 + RETURN();
  54 +}
  55 +
  56 +void OPPROTO glue(op_set_u32_T, REG) (void)
  57 +{
  58 + glue(T, REG) = (uint32_t)PARAM(1);
  59 + RETURN();
  60 +}
  61 +
  62 +#if 0 // Qemu does not know how to do this...
  63 +void OPPROTO glue(op_set_64_T, REG) (void)
  64 +{
  65 + glue(T, REG) = (int64_t)PARAM(1);
  66 + RETURN();
  67 +}
  68 +#else
  69 +void OPPROTO glue(op_set_64_T, REG) (void)
  70 +{
  71 + glue(T, REG) = ((int64_t)PARAM(1) << 32) | (int64_t)PARAM(2);
  72 + RETURN();
  73 +}
  74 +#endif
  75 +
  76 +#endif /* REG < 3 */
  77 +
  78 +/* Fixed-point register moves */
  79 +#if REG < 31
  80 +void OPPROTO glue(op_load_T0_ir, REG) (void)
  81 +{
  82 + T0 = env->ir[REG];
  83 + RETURN();
  84 +}
  85 +
  86 +void OPPROTO glue(op_load_T1_ir, REG) (void)
  87 +{
  88 + T1 = env->ir[REG];
  89 + RETURN();
  90 +}
  91 +
  92 +void OPPROTO glue(op_load_T2_ir, REG) (void)
  93 +{
  94 + T2 = env->ir[REG];
  95 + RETURN();
  96 +}
  97 +
  98 +void OPPROTO glue(op_store_T0_ir, REG) (void)
  99 +{
  100 + env->ir[REG] = T0;
  101 + RETURN();
  102 +}
  103 +
  104 +void OPPROTO glue(op_store_T1_ir, REG) (void)
  105 +{
  106 + env->ir[REG] = T1;
  107 + RETURN();
  108 +}
  109 +
  110 +void OPPROTO glue(op_store_T2_ir, REG) (void)
  111 +{
  112 + env->ir[REG] = T2;
  113 + RETURN();
  114 +}
  115 +
  116 +void OPPROTO glue(op_cmov_ir, REG) (void)
  117 +{
  118 + if (T0)
  119 + env->ir[REG] = T1;
  120 + RETURN();
  121 +}
  122 +
  123 +/* floating point registers moves */
  124 +void OPPROTO glue(op_load_FT0_fir, REG) (void)
  125 +{
  126 + FT0 = env->fir[REG];
  127 + RETURN();
  128 +}
  129 +
  130 +void OPPROTO glue(op_load_FT1_fir, REG) (void)
  131 +{
  132 + FT1 = env->fir[REG];
  133 + RETURN();
  134 +}
  135 +
  136 +void OPPROTO glue(op_load_FT2_fir, REG) (void)
  137 +{
  138 + FT2 = env->fir[REG];
  139 + RETURN();
  140 +}
  141 +
  142 +void OPPROTO glue(op_store_FT0_fir, REG) (void)
  143 +{
  144 + env->fir[REG] = FT0;
  145 + RETURN();
  146 +}
  147 +
  148 +void OPPROTO glue(op_store_FT1_fir, REG) (void)
  149 +{
  150 + env->fir[REG] = FT1;
  151 + RETURN();
  152 +}
  153 +
  154 +void OPPROTO glue(op_store_FT2_fir, REG) (void)
  155 +{
  156 + env->fir[REG] = FT2;
  157 + RETURN();
  158 +}
  159 +
  160 +void OPPROTO glue(op_cmov_fir, REG) (void)
  161 +{
  162 + helper_cmov_fir(REG);
  163 + RETURN();
  164 +}
  165 +#endif /* REG < 31 */
  166 +
  167 +#undef REG