Revision 7a3f1944
b/linux-user/sparc/syscall.h | ||
---|---|---|
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 |
}; |
b/linux-user/sparc/syscall_nr.h | ||
---|---|---|
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 |
b/target-sparc/cpu.h | ||
---|---|---|
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 |
b/target-sparc/exec.h | ||
---|---|---|
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 |
b/target-sparc/op.c | ||
---|---|---|
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 |
} |
b/target-sparc/op_template.h | ||
---|---|---|
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 |
b/target-sparc/translate.c | ||
---|---|---|
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 (); |
Also available in: Unified diff