Commit 7a3f194486ad5c8e21c96a19dee37b14a1057580

Authored by bellard
1 parent 2c0262af

sparc emulation target (thanx to Thomas M. Ogrisegg)


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@386 c046a42c-6fe2-441c-8c8c-71466251a162
linux-user/sparc/syscall.h 0 → 100644
  1 +struct target_pt_regs {
  2 + target_ulong psr;
  3 + target_ulong pc;
  4 + target_ulong npc;
  5 + target_ulong y;
  6 + target_ulong u_regs[16];
  7 +};
... ...
linux-user/sparc/syscall_nr.h 0 → 100644
  1 +#define TARGET_NR_exit 1 /* Common */
  2 +#define TARGET_NR_fork 2 /* Common */
  3 +#define TARGET_NR_read 3 /* Common */
  4 +#define TARGET_NR_write 4 /* Common */
  5 +#define TARGET_NR_open 5 /* Common */
  6 +#define TARGET_NR_close 6 /* Common */
  7 +#define TARGET_NR_wait4 7 /* Common */
  8 +#define TARGET_NR_creat 8 /* Common */
  9 +#define TARGET_NR_link 9 /* Common */
  10 +#define TARGET_NR_unlink 10 /* Common */
  11 +#define TARGET_NR_execv 11 /* SunOS Specific */
  12 +#define TARGET_NR_chdir 12 /* Common */
  13 +#define TARGET_NR_chown 13 /* Common */
  14 +#define TARGET_NR_mknod 14 /* Common */
  15 +#define TARGET_NR_chmod 15 /* Common */
  16 +#define TARGET_NR_lchown 16 /* Common */
  17 +#define TARGET_NR_brk 17 /* Common */
  18 +#define TARGET_NR_perfctr 18 /* Performance counter operations */
  19 +#define TARGET_NR_lseek 19 /* Common */
  20 +#define TARGET_NR_getpid 20 /* Common */
  21 +#define TARGET_NR_capget 21 /* Linux Specific */
  22 +#define TARGET_NR_capset 22 /* Linux Specific */
  23 +#define TARGET_NR_setuid 23 /* Implemented via setreuid in SunOS */
  24 +#define TARGET_NR_getuid 24 /* Common */
  25 +#define TARGET_NR_ptrace 26 /* Common */
  26 +#define TARGET_NR_alarm 27 /* Implemented via setitimer in SunOS */
  27 +#define TARGET_NR_sigaltstack 28 /* Common */
  28 +#define TARGET_NR_pause 29 /* Is sigblock(0)->sigpause() in SunOS */
  29 +#define TARGET_NR_utime 30 /* Implemented via utimes() under SunOS */
  30 +#define TARGET_NR_lchown32 31 /* Linux sparc32 specific */
  31 +#define TARGET_NR_fchown32 32 /* Linux sparc32 specific */
  32 +#define TARGET_NR_access 33 /* Common */
  33 +#define TARGET_NR_nice 34 /* Implemented via get/setpriority() in SunOS */
  34 +#define TARGET_NR_chown32 35 /* Linux sparc32 specific */
  35 +#define TARGET_NR_sync 36 /* Common */
  36 +#define TARGET_NR_kill 37 /* Common */
  37 +#define TARGET_NR_stat 38 /* Common */
  38 +#define TARGET_NR_sendfile 39 /* Linux Specific */
  39 +#define TARGET_NR_lstat 40 /* Common */
  40 +#define TARGET_NR_dup 41 /* Common */
  41 +#define TARGET_NR_pipe 42 /* Common */
  42 +#define TARGET_NR_times 43 /* Implemented via getrusage() in SunOS */
  43 +#define TARGET_NR_getuid32 44 /* Linux sparc32 specific */
  44 +#define TARGET_NR_umount2 45 /* Linux Specific */
  45 +#define TARGET_NR_setgid 46 /* Implemented via setregid() in SunOS */
  46 +#define TARGET_NR_getgid 47 /* Common */
  47 +#define TARGET_NR_signal 48 /* Implemented via sigvec() in SunOS */
  48 +#define TARGET_NR_geteuid 49 /* SunOS calls getuid() */
  49 +#define TARGET_NR_getegid 50 /* SunOS calls getgid() */
  50 +#define TARGET_NR_acct 51 /* Common */
  51 +#define TARGET_NR_getgid32 53 /* Linux sparc32 specific */
  52 +#define TARGET_NR_ioctl 54 /* Common */
  53 +#define TARGET_NR_reboot 55 /* Common */
  54 +#define TARGET_NR_mmap2 56 /* Linux sparc32 Specific */
  55 +#define TARGET_NR_symlink 57 /* Common */
  56 +#define TARGET_NR_readlink 58 /* Common */
  57 +#define TARGET_NR_execve 59 /* Common */
  58 +#define TARGET_NR_umask 60 /* Common */
  59 +#define TARGET_NR_chroot 61 /* Common */
  60 +#define TARGET_NR_fstat 62 /* Common */
  61 +#define TARGET_NR_fstat64 63 /* Linux sparc32 Specific */
  62 +#define TARGET_NR_getpagesize 64 /* Common */
  63 +#define TARGET_NR_msync 65 /* Common in newer 1.3.x revs... */
  64 +#define TARGET_NR_vfork 66 /* Common */
  65 +#define TARGET_NR_pread 67 /* Linux Specific */
  66 +#define TARGET_NR_pwrite 68 /* Linux Specific */
  67 +#define TARGET_NR_geteuid32 69 /* Linux sparc32, sbrk under SunOS */
  68 +#define TARGET_NR_getegid32 70 /* Linux sparc32, sstk under SunOS */
  69 +#define TARGET_NR_mmap 71 /* Common */
  70 +#define TARGET_NR_setreuid32 72 /* Linux sparc32, vadvise under SunOS */
  71 +#define TARGET_NR_munmap 73 /* Common */
  72 +#define TARGET_NR_mprotect 74 /* Common */
  73 +#define TARGET_NR_madvise 75 /* Common */
  74 +#define TARGET_NR_vhangup 76 /* Common */
  75 +#define TARGET_NR_truncate64 77 /* Linux sparc32 Specific */
  76 +#define TARGET_NR_mincore 78 /* Common */
  77 +#define TARGET_NR_getgroups 79 /* Common */
  78 +#define TARGET_NR_setgroups 80 /* Common */
  79 +#define TARGET_NR_getpgrp 81 /* Common */
  80 +#define TARGET_NR_setgroups32 82 /* Linux sparc32, setpgrp under SunOS */
  81 +#define TARGET_NR_setitimer 83 /* Common */
  82 +#define TARGET_NR_ftruncate64 84 /* Linux sparc32 Specific */
  83 +#define TARGET_NR_swapon 85 /* Common */
  84 +#define TARGET_NR_getitimer 86 /* Common */
  85 +#define TARGET_NR_setuid32 87 /* Linux sparc32, gethostname under SunOS */
  86 +#define TARGET_NR_sethostname 88 /* Common */
  87 +#define TARGET_NR_setgid32 89 /* Linux sparc32, getdtablesize under SunOS */
  88 +#define TARGET_NR_dup2 90 /* Common */
  89 +#define TARGET_NR_setfsuid32 91 /* Linux sparc32, getdopt under SunOS */
  90 +#define TARGET_NR_fcntl 92 /* Common */
  91 +#define TARGET_NR_select 93 /* Common */
  92 +#define TARGET_NR_setfsgid32 94 /* Linux sparc32, setdopt under SunOS */
  93 +#define TARGET_NR_fsync 95 /* Common */
  94 +#define TARGET_NR_setpriority 96 /* Common */
  95 +#define TARGET_NR_socket 97 /* Common */
  96 +#define TARGET_NR_connect 98 /* Common */
  97 +#define TARGET_NR_accept 99 /* Common */
  98 +#define TARGET_NR_getpriority 100 /* Common */
  99 +#define TARGET_NR_rt_sigreturn 101 /* Linux Specific */
  100 +#define TARGET_NR_rt_sigaction 102 /* Linux Specific */
  101 +#define TARGET_NR_rt_sigprocmask 103 /* Linux Specific */
  102 +#define TARGET_NR_rt_sigpending 104 /* Linux Specific */
  103 +#define TARGET_NR_rt_sigtimedwait 105 /* Linux Specific */
  104 +#define TARGET_NR_rt_sigqueueinfo 106 /* Linux Specific */
  105 +#define TARGET_NR_rt_sigsuspend 107 /* Linux Specific */
  106 +#define TARGET_NR_setresuid32 108 /* Linux Specific, sigvec under SunOS */
  107 +#define TARGET_NR_getresuid32 109 /* Linux Specific, sigblock under SunOS */
  108 +#define TARGET_NR_setresgid32 110 /* Linux Specific, sigsetmask under SunOS */
  109 +#define TARGET_NR_getresgid32 111 /* Linux Specific, sigpause under SunOS */
  110 +#define TARGET_NR_setregid32 112 /* Linux sparc32, sigstack under SunOS */
  111 +#define TARGET_NR_recvmsg 113 /* Common */
  112 +#define TARGET_NR_sendmsg 114 /* Common */
  113 +#define TARGET_NR_getgroups32 115 /* Linux sparc32, vtrace under SunOS */
  114 +#define TARGET_NR_gettimeofday 116 /* Common */
  115 +#define TARGET_NR_getrusage 117 /* Common */
  116 +#define TARGET_NR_getsockopt 118 /* Common */
  117 +#define TARGET_NR_getcwd 119 /* Linux Specific */
  118 +#define TARGET_NR_readv 120 /* Common */
  119 +#define TARGET_NR_writev 121 /* Common */
  120 +#define TARGET_NR_settimeofday 122 /* Common */
  121 +#define TARGET_NR_fchown 123 /* Common */
  122 +#define TARGET_NR_fchmod 124 /* Common */
  123 +#define TARGET_NR_recvfrom 125 /* Common */
  124 +#define TARGET_NR_setreuid 126 /* Common */
  125 +#define TARGET_NR_setregid 127 /* Common */
  126 +#define TARGET_NR_rename 128 /* Common */
  127 +#define TARGET_NR_truncate 129 /* Common */
  128 +#define TARGET_NR_ftruncate 130 /* Common */
  129 +#define TARGET_NR_flock 131 /* Common */
  130 +#define TARGET_NR_lstat64 132 /* Linux sparc32 Specific */
  131 +#define TARGET_NR_sendto 133 /* Common */
  132 +#define TARGET_NR_shutdown 134 /* Common */
  133 +#define TARGET_NR_socketpair 135 /* Common */
  134 +#define TARGET_NR_mkdir 136 /* Common */
  135 +#define TARGET_NR_rmdir 137 /* Common */
  136 +#define TARGET_NR_utimes 138 /* SunOS Specific */
  137 +#define TARGET_NR_stat64 139 /* Linux sparc32 Specific */
  138 +#define TARGET_NR_getpeername 141 /* Common */
  139 +#define TARGET_NR_gettid 143 /* ENOSYS under SunOS */
  140 +#define TARGET_NR_getrlimit 144 /* Common */
  141 +#define TARGET_NR_setrlimit 145 /* Common */
  142 +#define TARGET_NR_pivot_root 146 /* Linux Specific, killpg under SunOS */
  143 +#define TARGET_NR_prctl 147 /* ENOSYS under SunOS */
  144 +#define TARGET_NR_pciconfig_read 148 /* ENOSYS under SunOS */
  145 +#define TARGET_NR_pciconfig_write 149 /* ENOSYS under SunOS */
  146 +#define TARGET_NR_getsockname 150 /* Common */
  147 +#define TARGET_NR_poll 153 /* Common */
  148 +#define TARGET_NR_getdents64 154 /* Linux specific */
  149 +#define TARGET_NR_fcntl64 155 /* Linux sparc32 Specific */
  150 +#define TARGET_NR_statfs 157 /* Common */
  151 +#define TARGET_NR_fstatfs 158 /* Common */
  152 +#define TARGET_NR_umount 159 /* Common */
  153 +#define TARGET_NR_getdomainname 162 /* SunOS Specific */
  154 +#define TARGET_NR_setdomainname 163 /* Common */
  155 +#define TARGET_NR_quotactl 165 /* Common */
  156 +#define TARGET_NR_mount 167 /* Common */
  157 +#define TARGET_NR_ustat 168 /* Common */
  158 +#define TARGET_NR_getdents 174 /* Common */
  159 +#define TARGET_NR_setsid 175 /* Common */
  160 +#define TARGET_NR_fchdir 176 /* Common */
  161 +#define TARGET_NR_sigpending 183 /* Common */
  162 +#define TARGET_NR_query_module 184 /* Linux Specific */
  163 +#define TARGET_NR_setpgid 185 /* Common */
  164 +#define TARGET_NR_tkill 187 /* SunOS: fpathconf */
  165 +#define TARGET_NR_exit_group 188 /* Linux specific, sysconf undef SunOS */
  166 +#define TARGET_NR_uname 189 /* Linux Specific */
  167 +#define TARGET_NR_init_module 190 /* Linux Specific */
  168 +#define TARGET_NR_personality 191 /* Linux Specific */
  169 +#define TARGET_NR_getppid 197 /* Linux Specific */
  170 +#define TARGET_NR_sigaction 198 /* Linux Specific */
  171 +#define TARGET_NR_sgetmask 199 /* Linux Specific */
  172 +#define TARGET_NR_ssetmask 200 /* Linux Specific */
  173 +#define TARGET_NR_sigsuspend 201 /* Linux Specific */
  174 +#define TARGET_NR_oldlstat 202 /* Linux Specific */
  175 +#define TARGET_NR_uselib 203 /* Linux Specific */
  176 +#define TARGET_NR_readdir 204 /* Linux Specific */
  177 +#define TARGET_NR_readahead 205 /* Linux Specific */
  178 +#define TARGET_NR_socketcall 206 /* Linux Specific */
  179 +#define TARGET_NR_syslog 207 /* Linux Specific */
  180 +#define TARGET_NR_waitpid 212 /* Linux Specific */
  181 +#define TARGET_NR_swapoff 213 /* Linux Specific */
  182 +#define TARGET_NR_sysinfo 214 /* Linux Specific */
  183 +#define TARGET_NR_ipc 215 /* Linux Specific */
  184 +#define TARGET_NR_sigreturn 216 /* Linux Specific */
  185 +#define TARGET_NR_clone 217 /* Linux Specific */
  186 +#define TARGET_NR_adjtimex 219 /* Linux Specific */
  187 +#define TARGET_NR_sigprocmask 220 /* Linux Specific */
  188 +#define TARGET_NR_create_module 221 /* Linux Specific */
  189 +#define TARGET_NR_delete_module 222 /* Linux Specific */
  190 +#define TARGET_NR_get_kernel_syms 223 /* Linux Specific */
  191 +#define TARGET_NR_getpgid 224 /* Linux Specific */
  192 +#define TARGET_NR_bdflush 225 /* Linux Specific */
  193 +#define TARGET_NR_sysfs 226 /* Linux Specific */
  194 +#define TARGET_NR_afs_syscall 227 /* Linux Specific */
  195 +#define TARGET_NR_setfsuid 228 /* Linux Specific */
  196 +#define TARGET_NR_setfsgid 229 /* Linux Specific */
  197 +#define TARGET_NR__newselect 230 /* Linux Specific */
  198 +#define TARGET_NR_time 231 /* Linux Specific */
  199 +#define TARGET_NR_stime 233 /* Linux Specific */
  200 +#define TARGET_NR__llseek 236 /* Linux Specific */
  201 +#define TARGET_NR_mlock 237
  202 +#define TARGET_NR_munlock 238
  203 +#define TARGET_NR_mlockall 239
  204 +#define TARGET_NR_munlockall 240
  205 +#define TARGET_NR_sched_setparam 241
  206 +#define TARGET_NR_sched_getparam 242
  207 +#define TARGET_NR_sched_setscheduler 243
  208 +#define TARGET_NR_sched_getscheduler 244
  209 +#define TARGET_NR_sched_yield 245
  210 +#define TARGET_NR_sched_get_priority_max 246
  211 +#define TARGET_NR_sched_get_priority_min 247
  212 +#define TARGET_NR_sched_rr_get_interval 248
  213 +#define TARGET_NR_nanosleep 249
  214 +#define TARGET_NR_mremap 250
  215 +#define TARGET_NR__sysctl 251
  216 +#define TARGET_NR_getsid 252
  217 +#define TARGET_NR_fdatasync 253
  218 +#define TARGET_NR_nfsservctl 254
  219 +#define TARGET_NR_aplib 255
  220 +#define TARGET_NR__exit TARGET_NR_exit
... ...
target-sparc/cpu.h 0 → 100644
  1 +#ifndef CPU_SPARC_H
  2 +#define CPU_SPARC_H
  3 +
  4 +#include <setjmp.h>
  5 +#include "config.h"
  6 +#include "cpu-defs.h"
  7 +
  8 +/*#define EXCP_INTERRUPT 0x100*/
  9 +
  10 +
  11 +#define PSR_NEG (1<<23)
  12 +#define PSR_ZERO (1<<22)
  13 +#define PSR_OVF (1<<21)
  14 +#define PSR_CARRY (1<<20)
  15 +
  16 +typedef struct CPUSPARCState {
  17 + uint32_t gregs[8]; /* general registers */
  18 + uint32_t *regwptr; /* pointer to current register window */
  19 + double *regfptr; /* floating point registers */
  20 + uint32_t pc; /* program counter */
  21 + uint32_t npc; /* next program counter */
  22 + uint32_t sp; /* stack pointer */
  23 + uint32_t y; /* multiply/divide register */
  24 + uint32_t psr; /* processor state register */
  25 + uint32_t T2;
  26 + jmp_buf jmp_env;
  27 + int user_mode_only;
  28 + int exception_index;
  29 + int interrupt_index;
  30 + int interrupt_request;
  31 + struct TranslationBlock *current_tb;
  32 + void *opaque;
  33 +} CPUSPARCState;
  34 +
  35 +CPUSPARCState *cpu_sparc_init(void);
  36 +int cpu_sparc_exec(CPUSPARCState *s);
  37 +int cpu_sparc_close(CPUSPARCState *s);
  38 +
  39 +struct siginfo;
  40 +int cpu_sparc_signal_handler(int hostsignum, struct siginfo *info, void *puc);
  41 +void cpu_sparc_dump_state(CPUSPARCState *env, FILE *f, int flags);
  42 +
  43 +#define TARGET_PAGE_BITS 13
  44 +#include "cpu-all.h"
  45 +
  46 +#endif
... ...
target-sparc/exec.h 0 → 100644
  1 +#ifndef EXEC_SPARC_H
  2 +#define EXEC_SPARC_H 1
  3 +#include "dyngen-exec.h"
  4 +
  5 +register struct CPUSPARCState *env asm(AREG0);
  6 +register uint32_t T0 asm(AREG1);
  7 +register uint32_t T1 asm(AREG2);
  8 +register uint32_t T2 asm(AREG3);
  9 +
  10 +#include "cpu.h"
  11 +#include "exec-all.h"
  12 +
  13 +void cpu_lock(void);
  14 +void cpu_unlock(void);
  15 +void cpu_loop_exit(void);
  16 +#endif
... ...
target-sparc/op.c 0 → 100644
  1 +/*
  2 + SPARC micro operations
  3 +
  4 + Copyright (C) 2003 Thomas M. Ogrisegg <tom@fnord.at>
  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 +
  23 +/*XXX*/
  24 +#define REGNAME g0
  25 +#define REG (env->gregs[0])
  26 +#include "op_template.h"
  27 +#define REGNAME g1
  28 +#define REG (env->gregs[1])
  29 +#include "op_template.h"
  30 +#define REGNAME g2
  31 +#define REG (env->gregs[2])
  32 +#include "op_template.h"
  33 +#define REGNAME g3
  34 +#define REG (env->gregs[3])
  35 +#include "op_template.h"
  36 +#define REGNAME g4
  37 +#define REG (env->gregs[4])
  38 +#include "op_template.h"
  39 +#define REGNAME g5
  40 +#define REG (env->gregs[5])
  41 +#include "op_template.h"
  42 +#define REGNAME g6
  43 +#define REG (env->gregs[6])
  44 +#include "op_template.h"
  45 +#define REGNAME g7
  46 +#define REG (env->gregs[7])
  47 +#include "op_template.h"
  48 +#define REGNAME i0
  49 +#define REG (env->regwptr[16])
  50 +#include "op_template.h"
  51 +#define REGNAME i1
  52 +#define REG (env->regwptr[17])
  53 +#include "op_template.h"
  54 +#define REGNAME i2
  55 +#define REG (env->regwptr[18])
  56 +#include "op_template.h"
  57 +#define REGNAME i3
  58 +#define REG (env->regwptr[19])
  59 +#include "op_template.h"
  60 +#define REGNAME i4
  61 +#define REG (env->regwptr[20])
  62 +#include "op_template.h"
  63 +#define REGNAME i5
  64 +#define REG (env->regwptr[21])
  65 +#include "op_template.h"
  66 +#define REGNAME i6
  67 +#define REG (env->regwptr[22])
  68 +#include "op_template.h"
  69 +#define REGNAME i7
  70 +#define REG (env->regwptr[23])
  71 +#include "op_template.h"
  72 +#define REGNAME l0
  73 +#define REG (env->regwptr[8])
  74 +#include "op_template.h"
  75 +#define REGNAME l1
  76 +#define REG (env->regwptr[9])
  77 +#include "op_template.h"
  78 +#define REGNAME l2
  79 +#define REG (env->regwptr[10])
  80 +#include "op_template.h"
  81 +#define REGNAME l3
  82 +#define REG (env->regwptr[11])
  83 +#include "op_template.h"
  84 +#define REGNAME l4
  85 +#define REG (env->regwptr[12])
  86 +#include "op_template.h"
  87 +#define REGNAME l5
  88 +#define REG (env->regwptr[13])
  89 +#include "op_template.h"
  90 +#define REGNAME l6
  91 +#define REG (env->regwptr[14])
  92 +#include "op_template.h"
  93 +#define REGNAME l7
  94 +#define REG (env->regwptr[15])
  95 +#include "op_template.h"
  96 +#define REGNAME o0
  97 +#define REG (env->regwptr[0])
  98 +#include "op_template.h"
  99 +#define REGNAME o1
  100 +#define REG (env->regwptr[1])
  101 +#include "op_template.h"
  102 +#define REGNAME o2
  103 +#define REG (env->regwptr[2])
  104 +#include "op_template.h"
  105 +#define REGNAME o3
  106 +#define REG (env->regwptr[3])
  107 +#include "op_template.h"
  108 +#define REGNAME o4
  109 +#define REG (env->regwptr[4])
  110 +#include "op_template.h"
  111 +#define REGNAME o5
  112 +#define REG (env->regwptr[5])
  113 +#include "op_template.h"
  114 +#define REGNAME o6
  115 +#define REG (env->regwptr[6])
  116 +#include "op_template.h"
  117 +#define REGNAME o7
  118 +#define REG (env->regwptr[7])
  119 +#include "op_template.h"
  120 +
  121 +#define EIP (env->pc)
  122 +
  123 +void OPPROTO op_movl_T0_0(void)
  124 +{
  125 + T0 = 0;
  126 +}
  127 +
  128 +void OPPROTO op_movl_T0_1(void)
  129 +{
  130 + T0 = 1;
  131 +}
  132 +
  133 +void OPPROTO op_movl_T0_im(void)
  134 +{
  135 + T0 = PARAM1;
  136 +}
  137 +
  138 +void OPPROTO op_movl_T1_im(void)
  139 +{
  140 + T1 = PARAM1;
  141 +}
  142 +
  143 +void OPPROTO op_movl_T2_im(void)
  144 +{
  145 + T2 = PARAM1;
  146 +}
  147 +
  148 +void OPPROTO op_addl_T1_im(void)
  149 +{
  150 + T1 += PARAM1;
  151 +}
  152 +
  153 +void OPPROTO op_addl_T1_T2(void)
  154 +{
  155 + T1 += T2;
  156 +}
  157 +
  158 +void OPPROTO op_subl_T1_T2(void)
  159 +{
  160 + T1 -= T2;
  161 +}
  162 +
  163 +void OPPROTO op_add_T1_T0 (void)
  164 +{
  165 + T0 += T1;
  166 +}
  167 +
  168 +void OPPROTO op_and_T1_T0 (void)
  169 +{
  170 + T0 &= T1;
  171 +}
  172 +
  173 +void OPPROTO op_or_T1_T0 (void)
  174 +{
  175 + T0 |= T1;
  176 +}
  177 +
  178 +void OPPROTO op_xor_T1_T0 (void)
  179 +{
  180 + T0 ^= T1;
  181 +}
  182 +
  183 +void OPPROTO op_sub_T1_T0 (void)
  184 +{
  185 + T0 -= T1;
  186 +}
  187 +
  188 +void OPPROTO op_andn_T1_T0 (void)
  189 +{
  190 + T0 &= ~T1;
  191 +}
  192 +
  193 +void OPPROTO op_orn_T1_T0 (void)
  194 +{
  195 + T0 |= ~T1;
  196 +}
  197 +
  198 +void OPPROTO op_xnor_T1_T0 (void)
  199 +{
  200 + T0 ^= ~T1;
  201 +}
  202 +
  203 +void OPPROTO op_addx_T1_T0 (void)
  204 +{
  205 + T0 += T1+((env->psr & PSR_CARRY)?1:0);
  206 +}
  207 +
  208 +void OPPROTO op_umul_T1_T0 (void)
  209 +{
  210 + unsigned long long res = T0*T1;
  211 + T0 = res & 0xffffffff;
  212 + env->y = res >> 32;
  213 +}
  214 +
  215 +void OPPROTO op_smul_T1_T0 (void)
  216 +{
  217 + long long res = T0*T1;
  218 + T0 = res & 0xffffffff;
  219 + env->y = res >> 32;
  220 +}
  221 +
  222 +void OPPROTO op_udiv_T1_T0 (void)
  223 +{
  224 + unsigned long long x0 = T0 * env->y;
  225 + unsigned int x1 = T1;
  226 + T0 = x0 / x1;
  227 +}
  228 +
  229 +void OPPROTO op_sdiv_T1_T0 (void)
  230 +{
  231 + long long x0 = T0 * env->y;
  232 + int x1 = T1;
  233 + T0 = x0 / x1;
  234 +}
  235 +
  236 +void OPPROTO op_subx_T1_T0 (void)
  237 +{
  238 + T0 -= T1+((env->psr & PSR_CARRY)?1:0);
  239 +}
  240 +
  241 +void OPPROTO op_set_flags (void)
  242 +{
  243 + env->psr = 0;
  244 + if (!T0) env->psr |= PSR_ZERO;
  245 + if ((unsigned int) T0 < (unsigned int) T1) env->psr |= PSR_CARRY;
  246 + if ((int) T0 < (int) T1) env->psr |= PSR_OVF;
  247 + if ((int) T0 < 0) env->psr |= PSR_NEG;
  248 +}
  249 +
  250 +void OPPROTO op_sll (void)
  251 +{
  252 + T0 <<= T1;
  253 +}
  254 +
  255 +void OPPROTO op_srl (void)
  256 +{
  257 + T0 >>= T1;
  258 +}
  259 +
  260 +void OPPROTO op_sra (void)
  261 +{
  262 + int x = T0 >> T1;
  263 + T0 = x;
  264 +}
  265 +
  266 +void OPPROTO op_st (void)
  267 +{
  268 + stl ((void *) T0, T1);
  269 +}
  270 +
  271 +void OPPROTO op_stb (void)
  272 +{
  273 + stb ((void *) T0, T1);
  274 +}
  275 +
  276 +void OPPROTO op_sth (void)
  277 +{
  278 + stw ((void *) T0, T1);
  279 +}
  280 +
  281 +void OPPROTO op_ld (void)
  282 +{
  283 + T1 = ldl ((void *) T0);
  284 +}
  285 +
  286 +void OPPROTO op_ldub (void)
  287 +{
  288 + T1 = ldub ((void *) T0);
  289 +}
  290 +
  291 +void OPPROTO op_lduh (void)
  292 +{
  293 + T1 = lduw ((void *) T0);
  294 +}
  295 +
  296 +void OPPROTO op_ldsb (void)
  297 +{
  298 + T1 = ldsb ((void *) T0);
  299 +}
  300 +
  301 +void OPPROTO op_ldsh (void)
  302 +{
  303 + T1 = ldsw ((void *) T0);
  304 +}
  305 +
  306 +void OPPROTO op_ldstub (void)
  307 +{
  308 + T1 = ldub ((void *) T0);
  309 + stb ((void *) T0, 0xff); /* XXX: Should be Atomically */
  310 +}
  311 +
  312 +void OPPROTO op_swap (void)
  313 +{
  314 + unsigned int tmp = ldl ((void *) T0);
  315 + stl ((void *) T0, T1); /* XXX: Should be Atomically */
  316 + T1 = tmp;
  317 +}
  318 +
  319 +void OPPROTO op_ldd (void)
  320 +{
  321 + T1 = ldl ((void *) T0);
  322 + T0 = ldl ((void *) T0+4);
  323 +}
  324 +
  325 +void OPPROTO op_wry (void)
  326 +{
  327 + env->y = T0^T1;
  328 +}
  329 +
  330 +void OPPROTO op_rdy (void)
  331 +{
  332 + T0 = env->y;
  333 +}
  334 +
  335 +#define regwptr (env->regwptr)
  336 +
  337 +void OPPROTO op_save (void)
  338 +{
  339 + regwptr -= 16;
  340 +}
  341 +
  342 +void OPPROTO op_restore (void)
  343 +{
  344 + regwptr += 16;
  345 +}
  346 +
  347 +void OPPROTO op_trap (void)
  348 +{
  349 + env->exception_index = PARAM1;
  350 + cpu_loop_exit ();
  351 +}
  352 +
  353 +void OPPROTO op_exit_tb (void)
  354 +{
  355 + EXIT_TB ();
  356 +}
  357 +
  358 +void OPPROTO op_eval_be (void)
  359 +{
  360 + T0 = (env->psr & PSR_ZERO);
  361 +}
  362 +
  363 +#define FLAG_SET(x) (env->psr&x)?1:0
  364 +#define GET_FLAGS unsigned int Z = FLAG_SET(PSR_ZERO), N = FLAG_SET(PSR_NEG), V = FLAG_SET(PSR_OVF), C = FLAG_SET(PSR_CARRY)
  365 +
  366 +void OPPROTO op_eval_ble (void)
  367 +{
  368 + GET_FLAGS;
  369 + T0 = Z | (N^V);
  370 +}
  371 +
  372 +void OPPROTO op_eval_bl (void)
  373 +{
  374 + GET_FLAGS;
  375 + T0 = N^V;
  376 +}
  377 +
  378 +void OPPROTO op_eval_bleu (void)
  379 +{
  380 + GET_FLAGS;
  381 + T0 = C|Z;
  382 +}
  383 +
  384 +void OPPROTO op_eval_bcs (void)
  385 +{
  386 + T0 = (env->psr & PSR_CARRY);
  387 +}
  388 +
  389 +void OPPROTO op_eval_bvs (void)
  390 +{
  391 + T0 = (env->psr & PSR_OVF);
  392 +}
  393 +
  394 +void OPPROTO op_eval_bneg (void)
  395 +{
  396 + T0 = (env->psr & PSR_NEG);
  397 +}
  398 +
  399 +void OPPROTO op_eval_bne (void)
  400 +{
  401 + T0 = !(env->psr & PSR_ZERO);
  402 +}
  403 +
  404 +void OPPROTO op_eval_bg (void)
  405 +{
  406 + GET_FLAGS;
  407 + T0 = !(Z | (N^V));
  408 +}
  409 +
  410 +/*XXX: This seems to be documented wrong in the SPARC V8 Manual
  411 + The manual states: !(N^V)
  412 + but I assume Z | !(N^V) to be correct */
  413 +void OPPROTO op_eval_bge (void)
  414 +{
  415 + GET_FLAGS;
  416 + T0 = Z | !(N^V);
  417 +}
  418 +
  419 +void OPPROTO op_eval_bgu (void)
  420 +{
  421 + GET_FLAGS;
  422 + T0 = !(C | Z);
  423 +}
  424 +
  425 +void OPPROTO op_eval_bcc (void)
  426 +{
  427 + T0 = !(env->psr & PSR_CARRY);
  428 +}
  429 +
  430 +void OPPROTO op_eval_bpos (void)
  431 +{
  432 + T0 = !(env->psr & PSR_NEG);
  433 +}
  434 +
  435 +void OPPROTO op_eval_bvc (void)
  436 +{
  437 + T0 = !(env->psr & PSR_OVF);
  438 +}
  439 +
  440 +void OPPROTO op_jmp_im (void)
  441 +{
  442 + env->pc = PARAM1;
  443 +}
  444 +
  445 +void OPPROTO op_call (void)
  446 +{
  447 + regwptr[7] = PARAM1-4;
  448 + env->pc = PARAM1+PARAM2;
  449 +}
  450 +
  451 +void OPPROTO op_jmpl (void)
  452 +{
  453 + env->npc = T0;
  454 +}
  455 +
  456 +void OPPROTO op_generic_jmp_1 (void)
  457 +{
  458 + T1 = PARAM1;
  459 + env->pc = PARAM1+PARAM2;
  460 +}
  461 +
  462 +void OPPROTO op_generic_jmp_2 (void)
  463 +{
  464 + T1 = PARAM1;
  465 + env->pc = env->npc;
  466 +}
  467 +
  468 +unsigned long old_T0;
  469 +
  470 +void OPPROTO op_save_T0 (void)
  471 +{
  472 + old_T0 = T0;
  473 +}
  474 +
  475 +void OPPROTO op_restore_T0 (void)
  476 +{
  477 + T0 = old_T0;
  478 +}
  479 +
  480 +void OPPROTO op_generic_branch (void)
  481 +{
  482 + if (T0)
  483 + JUMP_TB (__func__, PARAM1, 0, PARAM2);
  484 + else
  485 + JUMP_TB (__func__, PARAM1, 1, PARAM3);
  486 + FORCE_RET ();
  487 +}
  488 +
  489 +void OPPROTO op_generic_branch_a (void)
  490 +{
  491 + if (T0)
  492 + env->npc = PARAM3;
  493 + else
  494 + JUMP_TB (__func__, PARAM1, 0, PARAM2);
  495 + FORCE_RET ();
  496 +}
  497 +
  498 +void OPPROTO op_noop (void)
  499 +{
  500 +}
... ...
target-sparc/op_template.h 0 → 100644
  1 +/*
  2 + * SPARC micro operations (templates for various register related
  3 + * operations)
  4 + *
  5 + * Copyright (c) 2003 Fabrice Bellard
  6 + *
  7 + * This library is free software; you can redistribute it and/or
  8 + * modify it under the terms of the GNU Lesser General Public
  9 + * License as published by the Free Software Foundation; either
  10 + * version 2 of the License, or (at your option) any later version.
  11 + *
  12 + * This library is distributed in the hope that it will be useful,
  13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15 + * Lesser General Public License for more details.
  16 + *
  17 + * You should have received a copy of the GNU Lesser General Public
  18 + * License along with this library; if not, write to the Free Software
  19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  20 + */
  21 +
  22 +void OPPROTO glue(op_movl_T0_, REGNAME)(void)
  23 +{
  24 + T0 = REG;
  25 +}
  26 +
  27 +void OPPROTO glue(op_movl_T1_, REGNAME)(void)
  28 +{
  29 + T1 = REG;
  30 +}
  31 +
  32 +void OPPROTO glue(op_movl_T2_, REGNAME)(void)
  33 +{
  34 + T2 = REG;
  35 +}
  36 +
  37 +void OPPROTO glue(glue(op_movl_, REGNAME), _T0)(void)
  38 +{
  39 + REG = T0;
  40 +}
  41 +
  42 +void OPPROTO glue(glue(op_movl_, REGNAME), _T1)(void)
  43 +{
  44 + REG = T1;
  45 +}
  46 +
  47 +#undef REG
  48 +#undef REGNAME
... ...
target-sparc/translate.c 0 → 100644
  1 +/*
  2 + SPARC translation
  3 +
  4 + Copyright (C) 2003 Thomas M. Ogrisegg <tom@fnord.at>
  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 +/*
  22 + SPARC has two pitfalls: Delay slots and (a)nullification.
  23 + This is currently solved as follows:
  24 +
  25 + 'call' instructions simply execute the delay slot before the actual
  26 + control transfer instructions.
  27 +
  28 + 'jmpl' instructions execute calculate the destination, then execute
  29 + the delay slot and then do the control transfer.
  30 +
  31 + (conditional) branch instructions are the most difficult ones, as the
  32 + delay slot may be nullified (ie. not executed). This happens when a
  33 + conditional branch is not executed (thus no control transfer happens)
  34 + and the 'anull' bit in the branch instruction opcode is set. This is
  35 + currently solved by doing a jump after the delay slot instruction.
  36 +
  37 + There is also one big (currently unsolved) bug in the branch code:
  38 + If a delay slot modifies the condition codes then the new condition
  39 + codes, instead of the old ones will be used.
  40 +
  41 + TODO-list:
  42 +
  43 + FPU-Instructions
  44 + Coprocessor-Instructions
  45 + Fix above bug
  46 + Check signedness issues
  47 + Privileged instructions
  48 + Register window overflow/underflow check
  49 + Optimize synthetic instructions
  50 + Optional alignment and privileged instruction check
  51 +
  52 + -- TMO, 09/03/03
  53 + */
  54 +
  55 +#include <stdarg.h>
  56 +#include <stdlib.h>
  57 +#include <stdio.h>
  58 +#include <string.h>
  59 +#include <inttypes.h>
  60 +
  61 +#include "cpu.h"
  62 +#include "exec-all.h"
  63 +#include "disas.h"
  64 +
  65 +#define DEBUG_DISAS
  66 +
  67 +typedef struct DisasContext {
  68 + uint8_t *pc;
  69 + uint8_t *npc;
  70 + void (*branch) (struct DisasContext *, uint32_t, uint32_t);
  71 + unsigned int delay_slot:2;
  72 + uint32_t insn;
  73 + uint32_t target;
  74 + int is_br;
  75 + struct TranslationBlock *tb;
  76 +} DisasContext;
  77 +
  78 +static uint16_t *gen_opc_ptr;
  79 +static uint32_t *gen_opparam_ptr;
  80 +extern FILE *logfile;
  81 +extern int loglevel;
  82 +
  83 +enum {
  84 +#define DEF(s,n,copy_size) INDEX_op_ ## s,
  85 +#include "opc.h"
  86 +#undef DEF
  87 + NB_OPS
  88 +};
  89 +
  90 +#include "gen-op.h"
  91 +
  92 +#define GET_FIELD(X, FROM, TO) \
  93 + ((X) >> (31 - (TO)) & ((1 << ((TO) - (FROM) + 1)) - 1))
  94 +
  95 +#define IS_IMM (insn & (1<<13))
  96 +
  97 +static void disas_sparc_insn (DisasContext *dc);
  98 +
  99 +typedef void (GenOpFunc)(void);
  100 +typedef void (GenOpFunc1)(long);
  101 +typedef void (GenOpFunc2)(long, long);
  102 +typedef void (GenOpFunc3)(long, long, long);
  103 +
  104 +static GenOpFunc *gen_op_movl_TN_reg[2][32] = {
  105 + {
  106 + gen_op_movl_g0_T0,
  107 + gen_op_movl_g1_T0,
  108 + gen_op_movl_g2_T0,
  109 + gen_op_movl_g3_T0,
  110 + gen_op_movl_g4_T0,
  111 + gen_op_movl_g5_T0,
  112 + gen_op_movl_g6_T0,
  113 + gen_op_movl_g7_T0,
  114 + gen_op_movl_o0_T0,
  115 + gen_op_movl_o1_T0,
  116 + gen_op_movl_o2_T0,
  117 + gen_op_movl_o3_T0,
  118 + gen_op_movl_o4_T0,
  119 + gen_op_movl_o5_T0,
  120 + gen_op_movl_o6_T0,
  121 + gen_op_movl_o7_T0,
  122 + gen_op_movl_l0_T0,
  123 + gen_op_movl_l1_T0,
  124 + gen_op_movl_l2_T0,
  125 + gen_op_movl_l3_T0,
  126 + gen_op_movl_l4_T0,
  127 + gen_op_movl_l5_T0,
  128 + gen_op_movl_l6_T0,
  129 + gen_op_movl_l7_T0,
  130 + gen_op_movl_i0_T0,
  131 + gen_op_movl_i1_T0,
  132 + gen_op_movl_i2_T0,
  133 + gen_op_movl_i3_T0,
  134 + gen_op_movl_i4_T0,
  135 + gen_op_movl_i5_T0,
  136 + gen_op_movl_i6_T0,
  137 + gen_op_movl_i7_T0,
  138 + },
  139 + {
  140 + gen_op_movl_g0_T1,
  141 + gen_op_movl_g1_T1,
  142 + gen_op_movl_g2_T1,
  143 + gen_op_movl_g3_T1,
  144 + gen_op_movl_g4_T1,
  145 + gen_op_movl_g5_T1,
  146 + gen_op_movl_g6_T1,
  147 + gen_op_movl_g7_T1,
  148 + gen_op_movl_o0_T1,
  149 + gen_op_movl_o1_T1,
  150 + gen_op_movl_o2_T1,
  151 + gen_op_movl_o3_T1,
  152 + gen_op_movl_o4_T1,
  153 + gen_op_movl_o5_T1,
  154 + gen_op_movl_o6_T1,
  155 + gen_op_movl_o7_T1,
  156 + gen_op_movl_l0_T1,
  157 + gen_op_movl_l1_T1,
  158 + gen_op_movl_l2_T1,
  159 + gen_op_movl_l3_T1,
  160 + gen_op_movl_l4_T1,
  161 + gen_op_movl_l5_T1,
  162 + gen_op_movl_l6_T1,
  163 + gen_op_movl_l7_T1,
  164 + gen_op_movl_i0_T1,
  165 + gen_op_movl_i1_T1,
  166 + gen_op_movl_i2_T1,
  167 + gen_op_movl_i3_T1,
  168 + gen_op_movl_i4_T1,
  169 + gen_op_movl_i5_T1,
  170 + gen_op_movl_i6_T1,
  171 + gen_op_movl_i7_T1,
  172 + }
  173 +};
  174 +
  175 +static GenOpFunc *gen_op_movl_reg_TN[3][32] = {
  176 + {
  177 + gen_op_movl_T0_g0,
  178 + gen_op_movl_T0_g1,
  179 + gen_op_movl_T0_g2,
  180 + gen_op_movl_T0_g3,
  181 + gen_op_movl_T0_g4,
  182 + gen_op_movl_T0_g5,
  183 + gen_op_movl_T0_g6,
  184 + gen_op_movl_T0_g7,
  185 + gen_op_movl_T0_o0,
  186 + gen_op_movl_T0_o1,
  187 + gen_op_movl_T0_o2,
  188 + gen_op_movl_T0_o3,
  189 + gen_op_movl_T0_o4,
  190 + gen_op_movl_T0_o5,
  191 + gen_op_movl_T0_o6,
  192 + gen_op_movl_T0_o7,
  193 + gen_op_movl_T0_l0,
  194 + gen_op_movl_T0_l1,
  195 + gen_op_movl_T0_l2,
  196 + gen_op_movl_T0_l3,
  197 + gen_op_movl_T0_l4,
  198 + gen_op_movl_T0_l5,
  199 + gen_op_movl_T0_l6,
  200 + gen_op_movl_T0_l7,
  201 + gen_op_movl_T0_i0,
  202 + gen_op_movl_T0_i1,
  203 + gen_op_movl_T0_i2,
  204 + gen_op_movl_T0_i3,
  205 + gen_op_movl_T0_i4,
  206 + gen_op_movl_T0_i5,
  207 + gen_op_movl_T0_i6,
  208 + gen_op_movl_T0_i7,
  209 + },
  210 + {
  211 + gen_op_movl_T1_g0,
  212 + gen_op_movl_T1_g1,
  213 + gen_op_movl_T1_g2,
  214 + gen_op_movl_T1_g3,
  215 + gen_op_movl_T1_g4,
  216 + gen_op_movl_T1_g5,
  217 + gen_op_movl_T1_g6,
  218 + gen_op_movl_T1_g7,
  219 + gen_op_movl_T1_o0,
  220 + gen_op_movl_T1_o1,
  221 + gen_op_movl_T1_o2,
  222 + gen_op_movl_T1_o3,
  223 + gen_op_movl_T1_o4,
  224 + gen_op_movl_T1_o5,
  225 + gen_op_movl_T1_o6,
  226 + gen_op_movl_T1_o7,
  227 + gen_op_movl_T1_l0,
  228 + gen_op_movl_T1_l1,
  229 + gen_op_movl_T1_l2,
  230 + gen_op_movl_T1_l3,
  231 + gen_op_movl_T1_l4,
  232 + gen_op_movl_T1_l5,
  233 + gen_op_movl_T1_l6,
  234 + gen_op_movl_T1_l7,
  235 + gen_op_movl_T1_i0,
  236 + gen_op_movl_T1_i1,
  237 + gen_op_movl_T1_i2,
  238 + gen_op_movl_T1_i3,
  239 + gen_op_movl_T1_i4,
  240 + gen_op_movl_T1_i5,
  241 + gen_op_movl_T1_i6,
  242 + gen_op_movl_T1_i7,
  243 + },
  244 + {
  245 + gen_op_movl_T2_g0,
  246 + gen_op_movl_T2_g1,
  247 + gen_op_movl_T2_g2,
  248 + gen_op_movl_T2_g3,
  249 + gen_op_movl_T2_g4,
  250 + gen_op_movl_T2_g5,
  251 + gen_op_movl_T2_g6,
  252 + gen_op_movl_T2_g7,
  253 + gen_op_movl_T2_o0,
  254 + gen_op_movl_T2_o1,
  255 + gen_op_movl_T2_o2,
  256 + gen_op_movl_T2_o3,
  257 + gen_op_movl_T2_o4,
  258 + gen_op_movl_T2_o5,
  259 + gen_op_movl_T2_o6,
  260 + gen_op_movl_T2_o7,
  261 + gen_op_movl_T2_l0,
  262 + gen_op_movl_T2_l1,
  263 + gen_op_movl_T2_l2,
  264 + gen_op_movl_T2_l3,
  265 + gen_op_movl_T2_l4,
  266 + gen_op_movl_T2_l5,
  267 + gen_op_movl_T2_l6,
  268 + gen_op_movl_T2_l7,
  269 + gen_op_movl_T2_i0,
  270 + gen_op_movl_T2_i1,
  271 + gen_op_movl_T2_i2,
  272 + gen_op_movl_T2_i3,
  273 + gen_op_movl_T2_i4,
  274 + gen_op_movl_T2_i5,
  275 + gen_op_movl_T2_i6,
  276 + gen_op_movl_T2_i7,
  277 + }
  278 +};
  279 +
  280 +static GenOpFunc1 *gen_op_movl_TN_im[3] = {
  281 + gen_op_movl_T0_im,
  282 + gen_op_movl_T1_im,
  283 + gen_op_movl_T2_im
  284 +};
  285 +
  286 +static inline void gen_movl_imm_TN (int reg, int imm)
  287 +{
  288 + gen_op_movl_TN_im[reg](imm);
  289 +}
  290 +
  291 +static inline void gen_movl_imm_T1 (int val)
  292 +{
  293 + gen_movl_imm_TN (1, val);
  294 +}
  295 +
  296 +static inline void gen_movl_imm_T0 (int val)
  297 +{
  298 + gen_movl_imm_TN (0, val);
  299 +}
  300 +
  301 +static inline void gen_movl_reg_TN (int reg, int t)
  302 +{
  303 + if (reg) gen_op_movl_reg_TN[t][reg]();
  304 + else gen_movl_imm_TN (t, 0);
  305 +}
  306 +
  307 +static inline void gen_movl_reg_T0 (int reg)
  308 +{
  309 + gen_movl_reg_TN (reg, 0);
  310 +}
  311 +
  312 +static inline void gen_movl_reg_T1 (int reg)
  313 +{
  314 + gen_movl_reg_TN (reg, 1);
  315 +}
  316 +
  317 +static inline void gen_movl_reg_T2 (int reg)
  318 +{
  319 + gen_movl_reg_TN (reg, 2);
  320 +}
  321 +
  322 +static inline void gen_movl_TN_reg (int reg, int t)
  323 +{
  324 + if (reg) gen_op_movl_TN_reg[t][reg]();
  325 +}
  326 +
  327 +static inline void gen_movl_T0_reg (int reg)
  328 +{
  329 + gen_movl_TN_reg (reg, 0);
  330 +}
  331 +
  332 +static inline void gen_movl_T1_reg (int reg)
  333 +{
  334 + gen_movl_TN_reg (reg, 1);
  335 +}
  336 +
  337 +static void do_branch (DisasContext *dc, uint32_t target, uint32_t insn)
  338 +{
  339 + unsigned int cond = GET_FIELD (insn, 3, 6), a = (insn & (1<<29)), ib = 0;
  340 + target += (uint32_t) dc->pc-4;
  341 + if (!a) disas_sparc_insn (dc);
  342 + switch (cond) {
  343 + case 0x0: gen_op_movl_T0_0 (); break;
  344 + case 0x1: gen_op_eval_be (); break;
  345 + case 0x2: gen_op_eval_ble (); break;
  346 + case 0x3: gen_op_eval_bl (); break;
  347 + case 0x4: gen_op_eval_bleu (); break;
  348 + case 0x5: gen_op_eval_bcs (); break;
  349 + case 0x6: gen_op_eval_bneg (); break;
  350 + case 0x7: gen_op_eval_bvs (); break;
  351 + case 0x8: gen_op_movl_T0_1 (); break;
  352 + case 0x9: gen_op_eval_bne (); break;
  353 + case 0xa: gen_op_eval_bg (); break;
  354 + case 0xb: gen_op_eval_bge (); break;
  355 + case 0xc: gen_op_eval_bgu (); break;
  356 + case 0xd: gen_op_eval_bcc (); break;
  357 + case 0xe: gen_op_eval_bpos (); break;
  358 + case 0xf: gen_op_eval_bvc (); break;
  359 + }
  360 + if (a && ((cond|0x8) != 0x8)) {
  361 + gen_op_generic_branch_a ((uint32_t) dc->tb,
  362 + (uint32_t) dc->pc+4, target);
  363 + disas_sparc_insn (dc);
  364 + ib = 1;
  365 + }
  366 + else
  367 + if (cond && !a) {
  368 + gen_op_generic_branch ((uint32_t) dc->tb, (uint32_t) target,
  369 + (uint32_t) dc->pc);
  370 + ib = 1;
  371 + }
  372 + if (ib) dc->is_br = DISAS_JUMP;
  373 +}
  374 +
  375 +/* target == 0x1 means CALL- else JMPL-instruction */
  376 +static void do_jump (DisasContext *dc, uint32_t target, uint32_t rd)
  377 +{
  378 + uint32_t orig_pc = (uint32_t) dc->pc-8;
  379 + if (target != 0x1)
  380 + gen_op_generic_jmp_1 (orig_pc, target);
  381 + else
  382 + gen_op_generic_jmp_2 (orig_pc);
  383 + gen_movl_T1_reg (rd);
  384 + dc->is_br = DISAS_JUMP;
  385 + gen_op_movl_T0_0 ();
  386 +}
  387 +
  388 +#define GET_FIELDs(x,a,b) sign_extend (GET_FIELD(x,a,b), b-a)
  389 +
  390 +static int
  391 +sign_extend (x, len)
  392 + int x, len;
  393 +{
  394 + int signbit = (1 << (len - 1));
  395 + int mask = (signbit << 1) - 1;
  396 + return ((x & mask) ^ signbit) - signbit;
  397 +}
  398 +
  399 +static void disas_sparc_insn (DisasContext *dc)
  400 +{
  401 + unsigned int insn, opc, rs1, rs2, rd;
  402 +
  403 + if (dc->delay_slot == 1) {
  404 + insn = dc->insn;
  405 + } else {
  406 + if (dc->delay_slot) dc->delay_slot--;
  407 + insn = htonl (*(unsigned int *) (dc->pc));
  408 + dc->pc += 4;
  409 + }
  410 +
  411 + opc = GET_FIELD (insn, 0, 1);
  412 +
  413 + rd = GET_FIELD (insn, 2, 6);
  414 + switch (opc) {
  415 + case 0: /* branches/sethi */
  416 + {
  417 + unsigned int xop = GET_FIELD (insn, 7, 9);
  418 + int target;
  419 + target = GET_FIELD (insn, 10, 31);
  420 + switch (xop) {
  421 + case 0x0: case 0x1: /* UNIMPL */
  422 + printf ("UNIMPLEMENTED: %p\n", dc->pc-4);
  423 + exit (23);
  424 + break;
  425 + case 0x2: /* BN+x */
  426 + {
  427 + target <<= 2;
  428 + target = sign_extend (target, 22);
  429 + do_branch (dc, target, insn);
  430 + break;
  431 + }
  432 + case 0x3: /* FBN+x */
  433 + break;
  434 + case 0x4: /* SETHI */
  435 + gen_movl_imm_T0 (target<<10);
  436 + gen_movl_T0_reg (rd);
  437 + break;
  438 + case 0x5: /*CBN+x*/
  439 + break;
  440 + }
  441 + break;
  442 + }
  443 + case 1: /*CALL*/
  444 + {
  445 + unsigned int target = GET_FIELDs (insn, 2, 31) << 2;
  446 + if (dc->delay_slot) {
  447 + do_jump (dc, target, 15);
  448 + dc->delay_slot = 0;
  449 + } else {
  450 + dc->insn = insn;
  451 + dc->delay_slot = 2;
  452 + }
  453 + break;
  454 + }
  455 + case 2: /* FPU & Logical Operations */
  456 + {
  457 + unsigned int xop = GET_FIELD (insn, 7, 12);
  458 + if (xop == 58) { /* generate trap */
  459 + dc->is_br = DISAS_JUMP;
  460 + gen_op_jmp_im ((uint32_t) dc->pc);
  461 + if (IS_IMM) gen_op_trap (GET_FIELD (insn, 25, 31));
  462 + /* else XXX*/
  463 + gen_op_movl_T0_0 ();
  464 + break;
  465 + }
  466 + if (xop == 0x34 || xop == 0x35) { /* FPU Operations */
  467 + exit (33);
  468 + }
  469 + rs1 = GET_FIELD (insn, 13, 17);
  470 + gen_movl_reg_T0 (rs1);
  471 + if (IS_IMM) { /* immediate */
  472 + rs2 = GET_FIELDs (insn, 20, 31);
  473 + gen_movl_imm_T1 (rs2);
  474 + } else { /* register */
  475 + rs2 = GET_FIELD (insn, 27, 31);
  476 + gen_movl_reg_T1 (rs2);
  477 + }
  478 + if (xop < 0x20) {
  479 + switch (xop &~ 0x10) {
  480 + case 0x0:
  481 + gen_op_add_T1_T0 ();
  482 + break;
  483 + case 0x1:
  484 + gen_op_and_T1_T0 ();
  485 + break;
  486 + case 0x2:
  487 + gen_op_or_T1_T0 ();
  488 + break;
  489 + case 0x3:
  490 + gen_op_xor_T1_T0 ();
  491 + break;
  492 + case 0x4:
  493 + gen_op_sub_T1_T0 ();
  494 + break;
  495 + case 0x5:
  496 + gen_op_andn_T1_T0 ();
  497 + break;
  498 + case 0x6:
  499 + gen_op_orn_T1_T0 ();
  500 + break;
  501 + case 0x7:
  502 + gen_op_xnor_T1_T0 ();
  503 + break;
  504 + case 0x8:
  505 + gen_op_addx_T1_T0 ();
  506 + break;
  507 + case 0xa:
  508 + gen_op_umul_T1_T0 ();
  509 + break;
  510 + case 0xb:
  511 + gen_op_smul_T1_T0 ();
  512 + break;
  513 + case 0xc:
  514 + gen_op_subx_T1_T0 ();
  515 + break;
  516 + case 0xe:
  517 + gen_op_udiv_T1_T0 ();
  518 + break;
  519 + case 0xf:
  520 + gen_op_sdiv_T1_T0 ();
  521 + break;
  522 + default:
  523 + exit (17);
  524 + break;
  525 + }
  526 + gen_movl_T0_reg (rd);
  527 + if (xop & 0x10) {
  528 + gen_op_set_flags ();
  529 + }
  530 + } else {
  531 + switch (xop) {
  532 + case 0x25: /* SLL */
  533 + gen_op_sll ();
  534 + break;
  535 + case 0x26:
  536 + gen_op_srl ();
  537 + break;
  538 + case 0x27:
  539 + gen_op_sra ();
  540 + break;
  541 + case 0x28: case 0x30:
  542 + {
  543 + unsigned int rdi = GET_FIELD (insn, 13, 17);
  544 + if (!rdi) (xop==0x28?gen_op_rdy ():gen_op_wry());
  545 + /* else gen_op_su_trap (); */
  546 + break;
  547 + }
  548 + /* Problem with jmpl: if restore is executed in the delay
  549 + slot, then the wrong registers are beeing used */
  550 + case 0x38: /* jmpl */
  551 + {
  552 + if (dc->delay_slot) {
  553 + gen_op_add_T1_T0 ();
  554 + do_jump (dc, 1, rd);
  555 + dc->delay_slot = 0;
  556 + } else {
  557 + gen_op_add_T1_T0 ();
  558 + gen_op_jmpl ();
  559 + dc->insn = insn;
  560 + dc->delay_slot = 2;
  561 + }
  562 + break;
  563 + }
  564 + case 0x3c: /* save */
  565 + gen_op_add_T1_T0 ();
  566 + gen_op_save ();
  567 + gen_movl_T0_reg (rd);
  568 + break;
  569 + case 0x3d: /* restore */
  570 + gen_op_add_T1_T0 ();
  571 + gen_op_restore ();
  572 + gen_movl_T0_reg (rd);
  573 + break;
  574 + }
  575 + }
  576 + break;
  577 + }
  578 + case 3: /* load/store instructions */
  579 + {
  580 + unsigned int xop = GET_FIELD (insn, 7, 12);
  581 + rs1 = GET_FIELD (insn, 13, 17);
  582 + gen_movl_reg_T0 (rs1);
  583 + if (IS_IMM) { /* immediate */
  584 + rs2 = GET_FIELDs (insn, 20, 31);
  585 + gen_movl_imm_T1 (rs2);
  586 + } else { /* register */
  587 + rs2 = GET_FIELD (insn, 27, 31);
  588 + gen_movl_reg_T1 (rs2);
  589 + }
  590 + gen_op_add_T1_T0 ();
  591 + if (xop < 4 || xop > 7) {
  592 + switch (xop) {
  593 + case 0x0: /* load word */
  594 + gen_op_ld ();
  595 + break;
  596 + case 0x1: /* load unsigned byte */
  597 + gen_op_ldub ();
  598 + break;
  599 + case 0x2: /* load unsigned halfword */
  600 + gen_op_lduh ();
  601 + break;
  602 + case 0x3: /* load double word */
  603 + gen_op_ldd ();
  604 + gen_movl_T0_reg (rd+1);
  605 + break;
  606 + case 0x9: /* load signed byte */
  607 + gen_op_ldsb ();
  608 + break;
  609 + case 0xa: /* load signed halfword */
  610 + gen_op_ldsh ();
  611 + break;
  612 + case 0xd: /* ldstub -- XXX: should be atomically */
  613 + gen_op_ldstub ();
  614 + break;
  615 + case 0x0f: /* swap register with memory. Also atomically */
  616 + gen_op_swap ();
  617 + break;
  618 + }
  619 + gen_movl_T1_reg (rd);
  620 + } else if (xop < 8) {
  621 + gen_movl_reg_T1 (rd);
  622 + switch (xop) {
  623 + case 0x4:
  624 + gen_op_st ();
  625 + break;
  626 + case 0x5:
  627 + gen_op_stb ();
  628 + break;
  629 + case 0x6:
  630 + gen_op_sth ();
  631 + break;
  632 + case 0x7:
  633 + gen_op_st ();
  634 + gen_movl_reg_T1 (rd+1);
  635 + gen_op_st ();
  636 + break;
  637 + }
  638 + }
  639 + }
  640 + }
  641 +}
  642 +
  643 +static inline int gen_intermediate_code_internal (TranslationBlock *tb, int spc)
  644 +{
  645 + uint8_t *pc_start = (uint8_t *) tb->pc;
  646 + uint16_t *gen_opc_end;
  647 + DisasContext dc;
  648 +
  649 + memset (&dc, 0, sizeof (dc));
  650 + if (spc) {
  651 + printf ("SearchPC not yet supported\n");
  652 + exit (0);
  653 + }
  654 + dc.tb = tb;
  655 + dc.pc = pc_start;
  656 +
  657 + gen_opc_ptr = gen_opc_buf;
  658 + gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
  659 + gen_opparam_ptr = gen_opparam_buf;
  660 +
  661 + do {
  662 + disas_sparc_insn (&dc);
  663 + } while (!dc.is_br && (gen_opc_ptr < gen_opc_end) &&
  664 + (dc.pc - pc_start) < (TARGET_PAGE_SIZE - 32));
  665 +
  666 + switch (dc.is_br) {
  667 + case DISAS_JUMP:
  668 + case DISAS_TB_JUMP:
  669 + gen_op_exit_tb ();
  670 + break;
  671 + }
  672 +
  673 + *gen_opc_ptr = INDEX_op_end;
  674 +#ifdef DEBUG_DISAS
  675 + if (loglevel) {
  676 + fprintf (logfile, "--------------\n");
  677 + fprintf (logfile, "IN: %s\n", lookup_symbol (pc_start));
  678 + disas(logfile, pc_start, dc.pc - pc_start, 0, 0);
  679 + fprintf(logfile, "\n");
  680 + fprintf(logfile, "OP:\n");
  681 + dump_ops(gen_opc_buf, gen_opparam_buf);
  682 + fprintf(logfile, "\n");
  683 + }
  684 +#endif
  685 +
  686 + return 0;
  687 +}
  688 +
  689 +int gen_intermediate_code (CPUSPARCState *env, TranslationBlock *tb)
  690 +{
  691 + return gen_intermediate_code_internal(tb, 0);
  692 +}
  693 +
  694 +int gen_intermediate_code_pc (CPUSPARCState *env, TranslationBlock *tb)
  695 +{
  696 + return gen_intermediate_code_internal(tb, 1);
  697 +}
  698 +
  699 +void *mycpu;
  700 +
  701 +CPUSPARCState *cpu_sparc_init (void)
  702 +{
  703 + CPUSPARCState *env;
  704 +
  705 + cpu_exec_init ();
  706 +
  707 + if (!(env = malloc (sizeof(CPUSPARCState))))
  708 + return (NULL);
  709 + memset (env, 0, sizeof (*env));
  710 + if (!(env->regwptr = malloc (0x2000)))
  711 + return (NULL);
  712 + memset (env->regwptr, 0, 0x2000);
  713 + env->regwptr += 127;
  714 + env->user_mode_only = 1;
  715 + mycpu = env;
  716 + return (env);
  717 +}
  718 +
  719 +#define GET_FLAG(a,b) ((env->psr & a)?b:'-')
  720 +
  721 +void cpu_sparc_dump_state (CPUSPARCState *env, FILE *f, int flags)
  722 +{
  723 + int i, x;
  724 +
  725 + fprintf (f, "@PC: %p\n", (void *) env->pc);
  726 + fprintf (f, "General Registers:\n");
  727 + for (i=0;i<4;i++)
  728 + fprintf (f, "%%g%c: %%%08x\t", i+'0', env->gregs[i]);
  729 + fprintf (f, "\n");
  730 + for (;i<8;i++)
  731 + fprintf (f, "%%g%c: %%%08x\t", i+'0', env->gregs[i]);
  732 + fprintf (f, "\nCurrent Register Window:\n");
  733 + for (x=0;x<3;x++) {
  734 + for (i=0;i<4;i++)
  735 + fprintf (f, "%%%c%d: %%%08x\t", (x==0?'o':(x==1?'l':'i')), i, env->regwptr[i+x*8]);
  736 + fprintf (f, "\n");
  737 + for (;i<8;i++)
  738 + fprintf (f, "%%%c%d: %%%08x\t", (x==0?'o':x==1?'l':'i'), i, env->regwptr[i+x*8]);
  739 + fprintf (f, "\n");
  740 + }
  741 + fprintf (f, "PSR: %x -> %c%c%c%c\n", env->psr,
  742 + GET_FLAG(PSR_ZERO, 'Z'), GET_FLAG(PSR_OVF, 'V'),
  743 + GET_FLAG(PSR_NEG, 'N'), GET_FLAG(PSR_CARRY, 'C'));
  744 +}
... ...