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 ();
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff