/[gxemul]/trunk/src/cpus/cpu_sparc_instr.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Contents of /trunk/src/cpus/cpu_sparc_instr.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 36 - (show annotations)
Mon Oct 8 16:21:34 2007 UTC (13 years, 1 month ago) by dpavlin
File MIME type: text/plain
File size: 45975 byte(s)
++ trunk/HISTORY	(local)
$Id: HISTORY,v 1.1497 2007/03/18 03:41:36 debug Exp $
20070224	Minor update to the initialization of the ns16550 in
		machine_walnut.c, to allow that machine type to boot with the
		new interrupt system (although it is still a dummy machine).
		Adding a wdc at 0x14000000 to machine_landisk.c, and fixing
		the SCIF serial interrupts of the SH4 cpu enough to get
		NetBSD/landisk booting from a disk image :-)  Adding a
		preliminary install instruction skeleton to guestoses.html.
20070306	Adding SH-IPL+G PROM emulation, and also passing the "end"
		symbol in r5 on bootup, for Landisk emulation. This is enough
		to get OpenBSD/landisk to install :)  Adding a preliminary
		install instruction skeleton to the documentation. SuperH
		emulation is still shaky, though :-/
20070307	Fixed a strangeness in memory_sh.c (read/write was never
		returned for any page). (Unknown whether this fixes any actual
		problems, though.)
20070308	dev_ram.c fix: invalidate code translations on writes to
		RAM, emulated as separate devices. Linux/dreamcast gets
		further in the boot process than before, but still bugs out
		in userland.
		Fixing bugs in the "stc.l gbr,@-rN" and "ldc.l @rN+,gbr" SuperH 
		instructions (they should NOT check the MD bit), allowing the
		Linux/dreamcast Live CD to reach userland correctly :-)
20070310	Changing the cpu name "Alpha" in src/useremul.c to "21364" to
		unbreak userland syscall emulation of FreeBSD/Alpha binaries.
20070314	Applying a patch from Michael Yaroslavtsev which fixes the
		previous Linux lib64 patch to the configure script.
20070315	Adding a (dummy) sun4v machine type, and SPARC T1 cpu type.
20070316	Creating a new directory, src/disk, and moving diskimage.c
		to it. Separating out bootblock loading stuff from emul.c into
		new files in src/disk.
		Adding some more SPARC registers.
20070318	Preparing/testing for a minirelease, 0.4.4.1.

==============  RELEASE 0.4.4.1  ==============


1 /*
2 * Copyright (C) 2005-2007 Anders Gavare. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
6 *
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * 3. The name of the author may not be used to endorse or promote products
13 * derived from this software without specific prior written permission.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 *
27 *
28 * $Id: cpu_sparc_instr.c,v 1.27 2007/03/16 15:43:58 debug Exp $
29 *
30 * SPARC instructions.
31 *
32 * Individual functions should keep track of cpu->n_translated_instrs.
33 * (If no instruction was executed, then it should be decreased. If, say, 4
34 * instructions were combined into one function and executed, then it should
35 * be increased by 3.)
36 */
37
38
39 /*
40 * invalid: For catching bugs.
41 */
42 X(invalid)
43 {
44 fatal("FATAL ERROR: An internal error occured in the SPARC"
45 " dyntrans code. Please contact the author with detailed"
46 " repro steps on how to trigger this bug.\n");
47 exit(1);
48 }
49
50
51 /*
52 * nop: Do nothing.
53 */
54 X(nop)
55 {
56 }
57
58
59 /*****************************************************************************/
60
61
62 /*
63 * call
64 *
65 * arg[0] = int32_t displacement compared to the current instruction
66 * arg[1] = int32_t displacement of current instruction compared to
67 * start of the page
68 */
69 X(call)
70 {
71 MODE_uint_t old_pc = cpu->pc;
72 old_pc &= ~((SPARC_IC_ENTRIES_PER_PAGE - 1)
73 << SPARC_INSTR_ALIGNMENT_SHIFT);
74 old_pc += (int32_t)ic->arg[1];
75 cpu->cd.sparc.r[SPARC_REG_O7] = old_pc;
76 cpu->delay_slot = TO_BE_DELAYED;
77 ic[1].f(cpu, ic+1);
78 cpu->n_translated_instrs ++;
79 if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
80 /* Note: Must be non-delayed when jumping to the new pc: */
81 cpu->delay_slot = NOT_DELAYED;
82 cpu->pc = old_pc + (int32_t)ic->arg[0];
83 quick_pc_to_pointers(cpu);
84 } else
85 cpu->delay_slot = NOT_DELAYED;
86 }
87 X(call_trace)
88 {
89 MODE_uint_t old_pc = cpu->pc;
90 old_pc &= ~((SPARC_IC_ENTRIES_PER_PAGE - 1)
91 << SPARC_INSTR_ALIGNMENT_SHIFT);
92 old_pc += (int32_t)ic->arg[1];
93 cpu->cd.sparc.r[SPARC_REG_O7] = old_pc;
94 cpu->delay_slot = TO_BE_DELAYED;
95 ic[1].f(cpu, ic+1);
96 cpu->n_translated_instrs ++;
97 if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
98 /* Note: Must be non-delayed when jumping to the new pc: */
99 cpu->delay_slot = NOT_DELAYED;
100 cpu->pc = old_pc + (int32_t)ic->arg[0];
101 cpu_functioncall_trace(cpu, cpu->pc);
102 quick_pc_to_pointers(cpu);
103 } else
104 cpu->delay_slot = NOT_DELAYED;
105 }
106
107
108 /*
109 * bl
110 *
111 * arg[0] = int32_t displacement compared to the start of the current page
112 */
113 X(bl)
114 {
115 MODE_uint_t old_pc = cpu->pc;
116 int n = (cpu->cd.sparc.ccr & SPARC_CCR_N) ? 1 : 0;
117 int v = (cpu->cd.sparc.ccr & SPARC_CCR_V) ? 1 : 0;
118 int cond = n ^ v;
119 cpu->delay_slot = TO_BE_DELAYED;
120 ic[1].f(cpu, ic+1);
121 cpu->n_translated_instrs ++;
122 if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
123 /* Note: Must be non-delayed when jumping to the new pc: */
124 cpu->delay_slot = NOT_DELAYED;
125 if (cond) {
126 old_pc &= ~((SPARC_IC_ENTRIES_PER_PAGE - 1)
127 << SPARC_INSTR_ALIGNMENT_SHIFT);
128 cpu->pc = old_pc + (int32_t)ic->arg[0];
129 quick_pc_to_pointers(cpu);
130 }
131 } else
132 cpu->delay_slot = NOT_DELAYED;
133 }
134 X(bl_xcc)
135 {
136 MODE_uint_t old_pc = cpu->pc;
137 int n = ((cpu->cd.sparc.ccr >> SPARC_CCR_XCC_SHIFT) & SPARC_CCR_N)? 1:0;
138 int v = ((cpu->cd.sparc.ccr >> SPARC_CCR_XCC_SHIFT) & SPARC_CCR_V)? 1:0;
139 int cond = n ^ v;
140 cpu->delay_slot = TO_BE_DELAYED;
141 ic[1].f(cpu, ic+1);
142 cpu->n_translated_instrs ++;
143 if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
144 /* Note: Must be non-delayed when jumping to the new pc: */
145 cpu->delay_slot = NOT_DELAYED;
146 if (cond) {
147 old_pc &= ~((SPARC_IC_ENTRIES_PER_PAGE - 1)
148 << SPARC_INSTR_ALIGNMENT_SHIFT);
149 cpu->pc = old_pc + (int32_t)ic->arg[0];
150 quick_pc_to_pointers(cpu);
151 }
152 } else
153 cpu->delay_slot = NOT_DELAYED;
154 }
155
156
157 /*
158 * ble
159 *
160 * arg[0] = int32_t displacement compared to the start of the current page
161 */
162 X(ble)
163 {
164 MODE_uint_t old_pc = cpu->pc;
165 int n = (cpu->cd.sparc.ccr & SPARC_CCR_N) ? 1 : 0;
166 int v = (cpu->cd.sparc.ccr & SPARC_CCR_V) ? 1 : 0;
167 int z = (cpu->cd.sparc.ccr & SPARC_CCR_Z) ? 1 : 0;
168 int cond = (n ^ v) || z;
169 cpu->delay_slot = TO_BE_DELAYED;
170 ic[1].f(cpu, ic+1);
171 cpu->n_translated_instrs ++;
172 if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
173 /* Note: Must be non-delayed when jumping to the new pc: */
174 cpu->delay_slot = NOT_DELAYED;
175 if (cond) {
176 old_pc &= ~((SPARC_IC_ENTRIES_PER_PAGE - 1)
177 << SPARC_INSTR_ALIGNMENT_SHIFT);
178 cpu->pc = old_pc + (int32_t)ic->arg[0];
179 quick_pc_to_pointers(cpu);
180 }
181 } else
182 cpu->delay_slot = NOT_DELAYED;
183 }
184 X(ble_xcc)
185 {
186 MODE_uint_t old_pc = cpu->pc;
187 int n = ((cpu->cd.sparc.ccr >> SPARC_CCR_XCC_SHIFT) & SPARC_CCR_N)? 1:0;
188 int v = ((cpu->cd.sparc.ccr >> SPARC_CCR_XCC_SHIFT) & SPARC_CCR_V)? 1:0;
189 int z = ((cpu->cd.sparc.ccr >> SPARC_CCR_XCC_SHIFT) & SPARC_CCR_Z)? 1:0;
190 int cond = (n ^ v) || z;
191 cpu->delay_slot = TO_BE_DELAYED;
192 ic[1].f(cpu, ic+1);
193 cpu->n_translated_instrs ++;
194 if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
195 /* Note: Must be non-delayed when jumping to the new pc: */
196 cpu->delay_slot = NOT_DELAYED;
197 if (cond) {
198 old_pc &= ~((SPARC_IC_ENTRIES_PER_PAGE - 1)
199 << SPARC_INSTR_ALIGNMENT_SHIFT);
200 cpu->pc = old_pc + (int32_t)ic->arg[0];
201 quick_pc_to_pointers(cpu);
202 }
203 } else
204 cpu->delay_slot = NOT_DELAYED;
205 }
206
207
208 /*
209 * bne
210 *
211 * arg[0] = int32_t displacement compared to the start of the current page
212 */
213 X(bne)
214 {
215 MODE_uint_t old_pc = cpu->pc;
216 int cond = (cpu->cd.sparc.ccr & SPARC_CCR_Z) ? 0 : 1;
217 cpu->delay_slot = TO_BE_DELAYED;
218 ic[1].f(cpu, ic+1);
219 cpu->n_translated_instrs ++;
220 if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
221 /* Note: Must be non-delayed when jumping to the new pc: */
222 cpu->delay_slot = NOT_DELAYED;
223 if (cond) {
224 old_pc &= ~((SPARC_IC_ENTRIES_PER_PAGE - 1)
225 << SPARC_INSTR_ALIGNMENT_SHIFT);
226 cpu->pc = old_pc + (int32_t)ic->arg[0];
227 quick_pc_to_pointers(cpu);
228 }
229 } else
230 cpu->delay_slot = NOT_DELAYED;
231 }
232 X(bne_a)
233 {
234 MODE_uint_t old_pc = cpu->pc;
235 int cond = (cpu->cd.sparc.ccr & SPARC_CCR_Z) ? 0 : 1;
236 cpu->delay_slot = TO_BE_DELAYED;
237 if (!cond) {
238 /* Nullify the delay slot: */
239 cpu->cd.sparc.next_ic ++;
240 return;
241 }
242 ic[1].f(cpu, ic+1);
243 cpu->n_translated_instrs ++;
244 if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
245 /* Note: Must be non-delayed when jumping to the new pc: */
246 cpu->delay_slot = NOT_DELAYED;
247 old_pc &= ~((SPARC_IC_ENTRIES_PER_PAGE - 1)
248 << SPARC_INSTR_ALIGNMENT_SHIFT);
249 cpu->pc = old_pc + (int32_t)ic->arg[0];
250 quick_pc_to_pointers(cpu);
251 } else
252 cpu->delay_slot = NOT_DELAYED;
253 }
254
255
256 /*
257 * bg
258 *
259 * arg[0] = int32_t displacement compared to the start of the current page
260 */
261 X(bg)
262 {
263 MODE_uint_t old_pc = cpu->pc;
264 int n = (cpu->cd.sparc.ccr & SPARC_CCR_N) ? 1 : 0;
265 int v = (cpu->cd.sparc.ccr & SPARC_CCR_V) ? 1 : 0;
266 int z = (cpu->cd.sparc.ccr & SPARC_CCR_Z) ? 1 : 0;
267 int cond = !(z | (n ^ v));
268 cpu->delay_slot = TO_BE_DELAYED;
269 ic[1].f(cpu, ic+1);
270 cpu->n_translated_instrs ++;
271 if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
272 /* Note: Must be non-delayed when jumping to the new pc: */
273 cpu->delay_slot = NOT_DELAYED;
274 if (cond) {
275 old_pc &= ~((SPARC_IC_ENTRIES_PER_PAGE - 1)
276 << SPARC_INSTR_ALIGNMENT_SHIFT);
277 cpu->pc = old_pc + (int32_t)ic->arg[0];
278 quick_pc_to_pointers(cpu);
279 }
280 } else
281 cpu->delay_slot = NOT_DELAYED;
282 }
283 X(bg_xcc)
284 {
285 MODE_uint_t old_pc = cpu->pc;
286 int n = ((cpu->cd.sparc.ccr >> SPARC_CCR_XCC_SHIFT) & SPARC_CCR_N)? 1:0;
287 int v = ((cpu->cd.sparc.ccr >> SPARC_CCR_XCC_SHIFT) & SPARC_CCR_V)? 1:0;
288 int z = ((cpu->cd.sparc.ccr >> SPARC_CCR_XCC_SHIFT) & SPARC_CCR_Z)? 1:0;
289 int cond = !(z | (n ^ v));
290 cpu->delay_slot = TO_BE_DELAYED;
291 ic[1].f(cpu, ic+1);
292 cpu->n_translated_instrs ++;
293 if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
294 /* Note: Must be non-delayed when jumping to the new pc: */
295 cpu->delay_slot = NOT_DELAYED;
296 if (cond) {
297 old_pc &= ~((SPARC_IC_ENTRIES_PER_PAGE - 1)
298 << SPARC_INSTR_ALIGNMENT_SHIFT);
299 cpu->pc = old_pc + (int32_t)ic->arg[0];
300 quick_pc_to_pointers(cpu);
301 }
302 } else
303 cpu->delay_slot = NOT_DELAYED;
304 }
305
306
307 /*
308 * bge
309 *
310 * arg[0] = int32_t displacement compared to the start of the current page
311 */
312 X(bge)
313 {
314 MODE_uint_t old_pc = cpu->pc;
315 int n = (cpu->cd.sparc.ccr & SPARC_CCR_N) ? 1 : 0;
316 int v = (cpu->cd.sparc.ccr & SPARC_CCR_V) ? 1 : 0;
317 int cond = !(n ^ v);
318 cpu->delay_slot = TO_BE_DELAYED;
319 ic[1].f(cpu, ic+1);
320 cpu->n_translated_instrs ++;
321 if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
322 /* Note: Must be non-delayed when jumping to the new pc: */
323 cpu->delay_slot = NOT_DELAYED;
324 if (cond) {
325 old_pc &= ~((SPARC_IC_ENTRIES_PER_PAGE - 1)
326 << SPARC_INSTR_ALIGNMENT_SHIFT);
327 cpu->pc = old_pc + (int32_t)ic->arg[0];
328 quick_pc_to_pointers(cpu);
329 }
330 } else
331 cpu->delay_slot = NOT_DELAYED;
332 }
333 X(bge_xcc)
334 {
335 MODE_uint_t old_pc = cpu->pc;
336 int n = ((cpu->cd.sparc.ccr >> SPARC_CCR_XCC_SHIFT) & SPARC_CCR_N)? 1:0;
337 int v = ((cpu->cd.sparc.ccr >> SPARC_CCR_XCC_SHIFT) & SPARC_CCR_V)? 1:0;
338 int cond = !(n ^ v);
339 cpu->delay_slot = TO_BE_DELAYED;
340 ic[1].f(cpu, ic+1);
341 cpu->n_translated_instrs ++;
342 if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
343 /* Note: Must be non-delayed when jumping to the new pc: */
344 cpu->delay_slot = NOT_DELAYED;
345 if (cond) {
346 old_pc &= ~((SPARC_IC_ENTRIES_PER_PAGE - 1)
347 << SPARC_INSTR_ALIGNMENT_SHIFT);
348 cpu->pc = old_pc + (int32_t)ic->arg[0];
349 quick_pc_to_pointers(cpu);
350 }
351 } else
352 cpu->delay_slot = NOT_DELAYED;
353 }
354
355
356 /*
357 * be
358 *
359 * arg[0] = int32_t displacement compared to the start of the current page
360 */
361 X(be)
362 {
363 MODE_uint_t old_pc = cpu->pc;
364 int cond = cpu->cd.sparc.ccr & SPARC_CCR_Z;
365 cpu->delay_slot = TO_BE_DELAYED;
366 ic[1].f(cpu, ic+1);
367 cpu->n_translated_instrs ++;
368 if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
369 /* Note: Must be non-delayed when jumping to the new pc: */
370 cpu->delay_slot = NOT_DELAYED;
371 if (cond) {
372 old_pc &= ~((SPARC_IC_ENTRIES_PER_PAGE - 1)
373 << SPARC_INSTR_ALIGNMENT_SHIFT);
374 cpu->pc = old_pc + (int32_t)ic->arg[0];
375 quick_pc_to_pointers(cpu);
376 }
377 } else
378 cpu->delay_slot = NOT_DELAYED;
379 }
380 X(be_xcc)
381 {
382 MODE_uint_t old_pc = cpu->pc;
383 int cond = (cpu->cd.sparc.ccr >> SPARC_CCR_XCC_SHIFT) & SPARC_CCR_Z;
384 cpu->delay_slot = TO_BE_DELAYED;
385 ic[1].f(cpu, ic+1);
386 cpu->n_translated_instrs ++;
387 if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
388 /* Note: Must be non-delayed when jumping to the new pc: */
389 cpu->delay_slot = NOT_DELAYED;
390 if (cond) {
391 old_pc &= ~((SPARC_IC_ENTRIES_PER_PAGE - 1)
392 << SPARC_INSTR_ALIGNMENT_SHIFT);
393 cpu->pc = old_pc + (int32_t)ic->arg[0];
394 quick_pc_to_pointers(cpu);
395 }
396 } else
397 cpu->delay_slot = NOT_DELAYED;
398 }
399
400
401 /*
402 * ba
403 *
404 * arg[0] = int32_t displacement compared to the start of the current page
405 */
406 X(ba)
407 {
408 MODE_uint_t old_pc = cpu->pc;
409 cpu->delay_slot = TO_BE_DELAYED;
410 ic[1].f(cpu, ic+1);
411 cpu->n_translated_instrs ++;
412 if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
413 /* Note: Must be non-delayed when jumping to the new pc: */
414 cpu->delay_slot = NOT_DELAYED;
415 old_pc &= ~((SPARC_IC_ENTRIES_PER_PAGE - 1)
416 << SPARC_INSTR_ALIGNMENT_SHIFT);
417 cpu->pc = old_pc + (int32_t)ic->arg[0];
418 quick_pc_to_pointers(cpu);
419 } else
420 cpu->delay_slot = NOT_DELAYED;
421 }
422
423
424 /*
425 * brnz
426 *
427 * arg[0] = int32_t displacement compared to the start of the current page
428 * arg[1] = ptr to rs1
429 */
430 X(brnz)
431 {
432 MODE_uint_t old_pc = cpu->pc;
433 int cond = reg(ic->arg[1]) != 0;
434 cpu->delay_slot = TO_BE_DELAYED;
435 ic[1].f(cpu, ic+1);
436 cpu->n_translated_instrs ++;
437 if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
438 /* Note: Must be non-delayed when jumping to the new pc: */
439 cpu->delay_slot = NOT_DELAYED;
440 if (cond) {
441 old_pc &= ~((SPARC_IC_ENTRIES_PER_PAGE - 1)
442 << SPARC_INSTR_ALIGNMENT_SHIFT);
443 cpu->pc = old_pc + (int32_t)ic->arg[0];
444 quick_pc_to_pointers(cpu);
445 }
446 } else
447 cpu->delay_slot = NOT_DELAYED;
448 }
449
450
451 /*
452 * Save:
453 *
454 * arg[0] = ptr to rs1
455 * arg[1] = ptr to rs2 or an immediate value (int32_t)
456 * arg[2] = ptr to rd (_after_ the register window change)
457 */
458 X(save_v9_imm)
459 {
460 MODE_uint_t rs = reg(ic->arg[0]) + (int32_t)ic->arg[1];
461 int cwp = cpu->cd.sparc.cwp;
462
463 if (cpu->cd.sparc.cansave == 0) {
464 fatal("save_v9_imm: spill trap. TODO\n");
465 exit(1);
466 }
467
468 if (cpu->cd.sparc.cleanwin - cpu->cd.sparc.canrestore == 0) {
469 fatal("save_v9_imm: clean_window trap. TODO\n");
470 exit(1);
471 }
472
473 /* Save away old in registers: */
474 memcpy(&cpu->cd.sparc.r_inout[cwp][0], &cpu->cd.sparc.r[SPARC_REG_I0],
475 sizeof(cpu->cd.sparc.r[SPARC_REG_I0]) * N_SPARC_INOUT_REG);
476
477 /* Save away old local registers: */
478 memcpy(&cpu->cd.sparc.r_local[cwp][0], &cpu->cd.sparc.r[SPARC_REG_L0],
479 sizeof(cpu->cd.sparc.r[SPARC_REG_L0]) * N_SPARC_INOUT_REG);
480
481 cpu->cd.sparc.cwp = (cwp + 1) % cpu->cd.sparc.cpu_type.nwindows;
482 cpu->cd.sparc.cansave --;
483 cpu->cd.sparc.canrestore ++; /* TODO: modulo here too? */
484 cwp = cpu->cd.sparc.cwp;
485
486 /* The out registers become the new in registers: */
487 memcpy(&cpu->cd.sparc.r[SPARC_REG_I0], &cpu->cd.sparc.r[SPARC_REG_O0],
488 sizeof(cpu->cd.sparc.r[SPARC_REG_O0]) * N_SPARC_INOUT_REG);
489
490 /* Read new local registers: */
491 memcpy(&cpu->cd.sparc.r[SPARC_REG_L0], &cpu->cd.sparc.r_local[cwp][0],
492 sizeof(cpu->cd.sparc.r[SPARC_REG_L0]) * N_SPARC_INOUT_REG);
493
494 reg(ic->arg[2]) = rs;
495 }
496
497
498 /*
499 * Restore:
500 */
501 X(restore)
502 {
503 int cwp = cpu->cd.sparc.cwp;
504
505 if (cpu->cd.sparc.canrestore == 0) {
506 fatal("restore: spill trap. TODO\n");
507 exit(1);
508 }
509
510 cpu->cd.sparc.cwp = cwp - 1;
511 if (cwp == 0)
512 cpu->cd.sparc.cwp = cpu->cd.sparc.cpu_type.nwindows - 1;
513 cpu->cd.sparc.cansave ++;
514 cpu->cd.sparc.canrestore --;
515 cwp = cpu->cd.sparc.cwp;
516
517 /* The in registers become the new out registers: */
518 memcpy(&cpu->cd.sparc.r[SPARC_REG_O0], &cpu->cd.sparc.r[SPARC_REG_I0],
519 sizeof(cpu->cd.sparc.r[SPARC_REG_O0]) * N_SPARC_INOUT_REG);
520
521 /* Read back the local registers: */
522 memcpy(&cpu->cd.sparc.r[SPARC_REG_L0], &cpu->cd.sparc.r_local[cwp][0],
523 sizeof(cpu->cd.sparc.r[SPARC_REG_L0]) * N_SPARC_INOUT_REG);
524
525 /* Read back the in registers: */
526 memcpy(&cpu->cd.sparc.r[SPARC_REG_I0], &cpu->cd.sparc.r_inout[cwp][0],
527 sizeof(cpu->cd.sparc.r[SPARC_REG_I0]) * N_SPARC_INOUT_REG);
528 }
529
530
531 /*
532 * Jump and link
533 *
534 * arg[0] = ptr to rs1
535 * arg[1] = ptr to rs2 or an immediate value (int32_t)
536 * arg[2] = ptr to rd
537 */
538 X(jmpl_imm)
539 {
540 int low_pc = ((size_t)ic - (size_t)cpu->cd.sparc.cur_ic_page)
541 / sizeof(struct sparc_instr_call);
542 cpu->pc &= ~((SPARC_IC_ENTRIES_PER_PAGE-1)
543 << SPARC_INSTR_ALIGNMENT_SHIFT);
544 cpu->pc += (low_pc << SPARC_INSTR_ALIGNMENT_SHIFT);
545 reg(ic->arg[2]) = cpu->pc;
546
547 cpu->delay_slot = TO_BE_DELAYED;
548 ic[1].f(cpu, ic+1);
549 cpu->n_translated_instrs ++;
550
551 if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
552 /* Note: Must be non-delayed when jumping to the new pc: */
553 cpu->delay_slot = NOT_DELAYED;
554 cpu->pc = reg(ic->arg[0]) + (int32_t)ic->arg[1];
555 quick_pc_to_pointers(cpu);
556 } else
557 cpu->delay_slot = NOT_DELAYED;
558 }
559 X(jmpl_imm_no_rd)
560 {
561 int low_pc = ((size_t)ic - (size_t)cpu->cd.sparc.cur_ic_page)
562 / sizeof(struct sparc_instr_call);
563 cpu->pc &= ~((SPARC_IC_ENTRIES_PER_PAGE-1)
564 << SPARC_INSTR_ALIGNMENT_SHIFT);
565 cpu->pc += (low_pc << SPARC_INSTR_ALIGNMENT_SHIFT);
566
567 cpu->delay_slot = TO_BE_DELAYED;
568 ic[1].f(cpu, ic+1);
569 cpu->n_translated_instrs ++;
570
571 if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
572 /* Note: Must be non-delayed when jumping to the new pc: */
573 cpu->delay_slot = NOT_DELAYED;
574 cpu->pc = reg(ic->arg[0]) + (int32_t)ic->arg[1];
575 quick_pc_to_pointers(cpu);
576 } else
577 cpu->delay_slot = NOT_DELAYED;
578 }
579 X(jmpl_reg)
580 {
581 int low_pc = ((size_t)ic - (size_t)cpu->cd.sparc.cur_ic_page)
582 / sizeof(struct sparc_instr_call);
583 cpu->pc &= ~((SPARC_IC_ENTRIES_PER_PAGE-1)
584 << SPARC_INSTR_ALIGNMENT_SHIFT);
585 cpu->pc += (low_pc << SPARC_INSTR_ALIGNMENT_SHIFT);
586 reg(ic->arg[2]) = cpu->pc;
587
588 cpu->delay_slot = TO_BE_DELAYED;
589 ic[1].f(cpu, ic+1);
590 cpu->n_translated_instrs ++;
591
592 if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
593 /* Note: Must be non-delayed when jumping to the new pc: */
594 cpu->delay_slot = NOT_DELAYED;
595 cpu->pc = reg(ic->arg[0]) + reg(ic->arg[1]);
596 quick_pc_to_pointers(cpu);
597 } else
598 cpu->delay_slot = NOT_DELAYED;
599 }
600 X(jmpl_reg_no_rd)
601 {
602 int low_pc = ((size_t)ic - (size_t)cpu->cd.sparc.cur_ic_page)
603 / sizeof(struct sparc_instr_call);
604 cpu->pc &= ~((SPARC_IC_ENTRIES_PER_PAGE-1)
605 << SPARC_INSTR_ALIGNMENT_SHIFT);
606 cpu->pc += (low_pc << SPARC_INSTR_ALIGNMENT_SHIFT);
607
608 cpu->delay_slot = TO_BE_DELAYED;
609 ic[1].f(cpu, ic+1);
610 cpu->n_translated_instrs ++;
611
612 if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
613 /* Note: Must be non-delayed when jumping to the new pc: */
614 cpu->delay_slot = NOT_DELAYED;
615 cpu->pc = reg(ic->arg[0]) + reg(ic->arg[1]);
616 quick_pc_to_pointers(cpu);
617 } else
618 cpu->delay_slot = NOT_DELAYED;
619 }
620
621
622 X(jmpl_imm_trace)
623 {
624 int low_pc = ((size_t)ic - (size_t)cpu->cd.sparc.cur_ic_page)
625 / sizeof(struct sparc_instr_call);
626 cpu->pc &= ~((SPARC_IC_ENTRIES_PER_PAGE-1)
627 << SPARC_INSTR_ALIGNMENT_SHIFT);
628 cpu->pc += (low_pc << SPARC_INSTR_ALIGNMENT_SHIFT);
629 reg(ic->arg[2]) = cpu->pc;
630
631 cpu->delay_slot = TO_BE_DELAYED;
632 ic[1].f(cpu, ic+1);
633 cpu->n_translated_instrs ++;
634
635 if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
636 /* Note: Must be non-delayed when jumping to the new pc: */
637 cpu->delay_slot = NOT_DELAYED;
638 cpu->pc = reg(ic->arg[0]) + (int32_t)ic->arg[1];
639 cpu_functioncall_trace(cpu, cpu->pc);
640 quick_pc_to_pointers(cpu);
641 } else
642 cpu->delay_slot = NOT_DELAYED;
643 }
644 X(jmpl_reg_trace)
645 {
646 int low_pc = ((size_t)ic - (size_t)cpu->cd.sparc.cur_ic_page)
647 / sizeof(struct sparc_instr_call);
648 cpu->pc &= ~((SPARC_IC_ENTRIES_PER_PAGE-1)
649 << SPARC_INSTR_ALIGNMENT_SHIFT);
650 cpu->pc += (low_pc << SPARC_INSTR_ALIGNMENT_SHIFT);
651 reg(ic->arg[2]) = cpu->pc;
652
653 cpu->delay_slot = TO_BE_DELAYED;
654 ic[1].f(cpu, ic+1);
655 cpu->n_translated_instrs ++;
656
657 if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
658 /* Note: Must be non-delayed when jumping to the new pc: */
659 cpu->delay_slot = NOT_DELAYED;
660 cpu->pc = reg(ic->arg[0]) + reg(ic->arg[1]);
661 cpu_functioncall_trace(cpu, cpu->pc);
662 quick_pc_to_pointers(cpu);
663 } else
664 cpu->delay_slot = NOT_DELAYED;
665 }
666 X(retl_trace)
667 {
668 int low_pc = ((size_t)ic - (size_t)cpu->cd.sparc.cur_ic_page)
669 / sizeof(struct sparc_instr_call);
670 cpu->pc &= ~((SPARC_IC_ENTRIES_PER_PAGE-1)
671 << SPARC_INSTR_ALIGNMENT_SHIFT);
672 cpu->pc += (low_pc << SPARC_INSTR_ALIGNMENT_SHIFT);
673
674 cpu->delay_slot = TO_BE_DELAYED;
675 ic[1].f(cpu, ic+1);
676 cpu->n_translated_instrs ++;
677
678 if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
679 /* Note: Must be non-delayed when jumping to the new pc: */
680 cpu->delay_slot = NOT_DELAYED;
681 cpu->pc = reg(ic->arg[0]) + (int32_t)ic->arg[1];
682 quick_pc_to_pointers(cpu);
683 cpu_functioncall_trace_return(cpu);
684 } else
685 cpu->delay_slot = NOT_DELAYED;
686 }
687
688
689 /*
690 * Return
691 *
692 * arg[0] = ptr to rs1
693 * arg[1] = ptr to rs2 or an immediate value (int32_t)
694 */
695 X(return_imm)
696 {
697 int low_pc = ((size_t)ic - (size_t)cpu->cd.sparc.cur_ic_page)
698 / sizeof(struct sparc_instr_call);
699 cpu->pc &= ~((SPARC_IC_ENTRIES_PER_PAGE-1)
700 << SPARC_INSTR_ALIGNMENT_SHIFT);
701 cpu->pc += (low_pc << SPARC_INSTR_ALIGNMENT_SHIFT);
702
703 cpu->delay_slot = TO_BE_DELAYED;
704 ic[1].f(cpu, ic+1);
705 cpu->n_translated_instrs ++;
706
707 if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
708 /* Note: Must be non-delayed when jumping to the new pc: */
709 cpu->delay_slot = NOT_DELAYED;
710 cpu->pc = reg(ic->arg[0]) + (int32_t)ic->arg[1];
711 quick_pc_to_pointers(cpu);
712 instr(restore)(cpu, ic);
713 } else
714 cpu->delay_slot = NOT_DELAYED;
715 }
716 X(return_reg)
717 {
718 int low_pc = ((size_t)ic - (size_t)cpu->cd.sparc.cur_ic_page)
719 / sizeof(struct sparc_instr_call);
720 cpu->pc &= ~((SPARC_IC_ENTRIES_PER_PAGE-1)
721 << SPARC_INSTR_ALIGNMENT_SHIFT);
722 cpu->pc += (low_pc << SPARC_INSTR_ALIGNMENT_SHIFT);
723
724 cpu->delay_slot = TO_BE_DELAYED;
725 ic[1].f(cpu, ic+1);
726 cpu->n_translated_instrs ++;
727
728 if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
729 /* Note: Must be non-delayed when jumping to the new pc: */
730 cpu->delay_slot = NOT_DELAYED;
731 cpu->pc = reg(ic->arg[0]) + reg(ic->arg[1]);
732 quick_pc_to_pointers(cpu);
733 instr(restore)(cpu, ic);
734 } else
735 cpu->delay_slot = NOT_DELAYED;
736 }
737 X(return_imm_trace)
738 {
739 int low_pc = ((size_t)ic - (size_t)cpu->cd.sparc.cur_ic_page)
740 / sizeof(struct sparc_instr_call);
741 cpu->pc &= ~((SPARC_IC_ENTRIES_PER_PAGE-1)
742 << SPARC_INSTR_ALIGNMENT_SHIFT);
743 cpu->pc += (low_pc << SPARC_INSTR_ALIGNMENT_SHIFT);
744
745 cpu->delay_slot = TO_BE_DELAYED;
746 ic[1].f(cpu, ic+1);
747 cpu->n_translated_instrs ++;
748
749 if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
750 /* Note: Must be non-delayed when jumping to the new pc: */
751 cpu->delay_slot = NOT_DELAYED;
752 cpu->pc = reg(ic->arg[0]) + (int32_t)ic->arg[1];
753 cpu_functioncall_trace(cpu, cpu->pc);
754 quick_pc_to_pointers(cpu);
755 instr(restore)(cpu, ic);
756 } else
757 cpu->delay_slot = NOT_DELAYED;
758 }
759 X(return_reg_trace)
760 {
761 int low_pc = ((size_t)ic - (size_t)cpu->cd.sparc.cur_ic_page)
762 / sizeof(struct sparc_instr_call);
763 cpu->pc &= ~((SPARC_IC_ENTRIES_PER_PAGE-1)
764 << SPARC_INSTR_ALIGNMENT_SHIFT);
765 cpu->pc += (low_pc << SPARC_INSTR_ALIGNMENT_SHIFT);
766
767 cpu->delay_slot = TO_BE_DELAYED;
768 ic[1].f(cpu, ic+1);
769 cpu->n_translated_instrs ++;
770
771 if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
772 /* Note: Must be non-delayed when jumping to the new pc: */
773 cpu->delay_slot = NOT_DELAYED;
774 cpu->pc = reg(ic->arg[0]) + reg(ic->arg[1]);
775 cpu_functioncall_trace(cpu, cpu->pc);
776 quick_pc_to_pointers(cpu);
777 instr(restore)(cpu, ic);
778 } else
779 cpu->delay_slot = NOT_DELAYED;
780 }
781
782
783 /*
784 * set: Set a register to a value (e.g. sethi).
785 *
786 * arg[0] = ptr to rd
787 * arg[1] = value (uint32_t)
788 */
789 X(set)
790 {
791 reg(ic->arg[0]) = (uint32_t)ic->arg[1];
792 }
793
794
795 /*
796 * Computational/arithmetic instructions:
797 *
798 * arg[0] = ptr to rs1
799 * arg[1] = ptr to rs2 or an immediate value (int32_t)
800 * arg[2] = ptr to rd
801 */
802 X(add) { reg(ic->arg[2]) = reg(ic->arg[0]) + reg(ic->arg[1]); }
803 X(add_imm) { reg(ic->arg[2]) = reg(ic->arg[0]) + (int32_t)ic->arg[1]; }
804 X(and) { reg(ic->arg[2]) = reg(ic->arg[0]) & reg(ic->arg[1]); }
805 X(and_imm) { reg(ic->arg[2]) = reg(ic->arg[0]) & (int32_t)ic->arg[1]; }
806 X(andn) { reg(ic->arg[2]) = reg(ic->arg[0]) & ~reg(ic->arg[1]); }
807 X(andn_imm) { reg(ic->arg[2]) = reg(ic->arg[0]) & ~(int32_t)ic->arg[1]; }
808 X(or) { reg(ic->arg[2]) = reg(ic->arg[0]) | reg(ic->arg[1]); }
809 X(or_imm) { reg(ic->arg[2]) = reg(ic->arg[0]) | (int32_t)ic->arg[1]; }
810 X(xor) { reg(ic->arg[2]) = reg(ic->arg[0]) ^ reg(ic->arg[1]); }
811 X(xor_imm) { reg(ic->arg[2]) = reg(ic->arg[0]) ^ (int32_t)ic->arg[1]; }
812 X(sub) { reg(ic->arg[2]) = reg(ic->arg[0]) - reg(ic->arg[1]); }
813 X(sub_imm) { reg(ic->arg[2]) = reg(ic->arg[0]) - (int32_t)ic->arg[1]; }
814
815 X(sll) { reg(ic->arg[2]) = (uint32_t)reg(ic->arg[0]) <<
816 (reg(ic->arg[1]) & 31); }
817 X(sllx) { reg(ic->arg[2]) = (uint64_t)reg(ic->arg[0]) <<
818 (reg(ic->arg[1]) & 63); }
819 X(sll_imm) { reg(ic->arg[2]) = (uint32_t)reg(ic->arg[0]) << ic->arg[1]; }
820 X(sllx_imm) { reg(ic->arg[2]) = (uint64_t)reg(ic->arg[0]) << ic->arg[1]; }
821
822 X(srl) { reg(ic->arg[2]) = (uint32_t)reg(ic->arg[0]) >>
823 (reg(ic->arg[1]) & 31); }
824 X(srlx) { reg(ic->arg[2]) = (uint64_t)reg(ic->arg[0]) >>
825 (reg(ic->arg[1]) & 63); }
826 X(srl_imm) { reg(ic->arg[2]) = (uint32_t)reg(ic->arg[0]) >> ic->arg[1]; }
827 X(srlx_imm) { reg(ic->arg[2]) = (uint64_t)reg(ic->arg[0]) >> ic->arg[1]; }
828
829 X(sra) { reg(ic->arg[2]) = (int32_t)reg(ic->arg[0]) >>
830 (reg(ic->arg[1]) & 31); }
831 X(srax) { reg(ic->arg[2]) = (int64_t)reg(ic->arg[0]) >>
832 (reg(ic->arg[1]) & 63); }
833 X(sra_imm) { reg(ic->arg[2]) = (int32_t)reg(ic->arg[0]) >> ic->arg[1]; }
834 X(srax_imm) { reg(ic->arg[2]) = (int64_t)reg(ic->arg[0]) >> ic->arg[1]; }
835
836 X(udiv)
837 {
838 uint64_t z = (cpu->cd.sparc.y << 32) | (uint32_t)reg(ic->arg[0]);
839 z /= (uint32_t)reg(ic->arg[1]);
840 if (z > 0xffffffff)
841 z = 0xffffffff;
842 reg(ic->arg[2]) = z;
843 }
844 X(udiv_imm)
845 {
846 uint64_t z = (cpu->cd.sparc.y << 32) | (uint32_t)reg(ic->arg[0]);
847 z /= (uint32_t)ic->arg[1];
848 if (z > 0xffffffff)
849 z = 0xffffffff;
850 reg(ic->arg[2]) = z;
851 }
852
853
854 /*
855 * Add with ccr update:
856 *
857 * arg[0] = ptr to rs1
858 * arg[1] = ptr to rs2 or an immediate value (int32_t)
859 * arg[2] = ptr to rd
860 */
861 int32_t sparc_addcc32(struct cpu *cpu, int32_t rs1, int32_t rs2);
862 #ifdef MODE32
863 int32_t sparc_addcc32(struct cpu *cpu, int32_t rs1, int32_t rs2)
864 #else
865 int64_t sparc_addcc64(struct cpu *cpu, int64_t rs1, int64_t rs2)
866 #endif
867 {
868 int cc = 0, sign1 = 0, sign2 = 0, signd = 0, mask = SPARC_CCR_ICC_MASK;
869 MODE_int_t rd = rs1 + rs2;
870 if (rd == 0)
871 cc = SPARC_CCR_Z;
872 else if (rd < 0)
873 cc = SPARC_CCR_N, signd = 1;
874 if (rs1 < 0)
875 sign1 = 1;
876 if (rs2 < 0)
877 sign2 = 1;
878 if (sign1 == sign2 && sign1 != signd)
879 cc |= SPARC_CCR_V;
880 /* TODO: SPARC_CCR_C */
881 #ifndef MODE32
882 mask <<= SPARC_CCR_XCC_SHIFT;
883 cc <<= SPARC_CCR_XCC_SHIFT;
884 #endif
885 cpu->cd.sparc.ccr &= ~mask;
886 cpu->cd.sparc.ccr |= cc;
887 return rd;
888 }
889 X(addcc)
890 {
891 /* Like add, but updates the ccr, and does both 32-bit and
892 64-bit comparison at the same time. */
893 MODE_int_t rs1 = reg(ic->arg[0]), rs2 = reg(ic->arg[1]), rd;
894 rd = sparc_addcc32(cpu, rs1, rs2);
895 #ifndef MODE32
896 rd = sparc_addcc64(cpu, rs1, rs2);
897 #endif
898 reg(ic->arg[2]) = rd;
899 }
900 X(addcc_imm)
901 {
902 MODE_int_t rs1 = reg(ic->arg[0]), rs2 = (int32_t)ic->arg[1], rd;
903 rd = sparc_addcc32(cpu, rs1, rs2);
904 #ifndef MODE32
905 rd = sparc_addcc64(cpu, rs1, rs2);
906 #endif
907 reg(ic->arg[2]) = rd;
908 }
909
910
911 /*
912 * And with ccr update:
913 *
914 * arg[0] = ptr to rs1
915 * arg[1] = ptr to rs2 or an immediate value (int32_t)
916 * arg[2] = ptr to rd
917 */
918 int32_t sparc_andcc32(struct cpu *cpu, int32_t rs1, int32_t rs2);
919 #ifdef MODE32
920 int32_t sparc_andcc32(struct cpu *cpu, int32_t rs1, int32_t rs2)
921 #else
922 int64_t sparc_andcc64(struct cpu *cpu, int64_t rs1, int64_t rs2)
923 #endif
924 {
925 int cc = 0, mask = SPARC_CCR_ICC_MASK;
926 MODE_int_t rd = rs1 & rs2;
927 if (rd == 0)
928 cc = SPARC_CCR_Z;
929 else if (rd < 0)
930 cc = SPARC_CCR_N;
931 /* Note: SPARC_CCR_C and SPARC_CCR_V are always zero. */
932 #ifndef MODE32
933 mask <<= SPARC_CCR_XCC_SHIFT;
934 cc <<= SPARC_CCR_XCC_SHIFT;
935 #endif
936 cpu->cd.sparc.ccr &= ~mask;
937 cpu->cd.sparc.ccr |= cc;
938 return rd;
939 }
940 X(andcc)
941 {
942 /* Like and, but updates the ccr, and does both 32-bit and
943 64-bit comparison at the same time. */
944 MODE_int_t rs1 = reg(ic->arg[0]), rs2 = reg(ic->arg[1]), rd;
945 rd = sparc_andcc32(cpu, rs1, rs2);
946 #ifndef MODE32
947 rd = sparc_andcc64(cpu, rs1, rs2);
948 #endif
949 reg(ic->arg[2]) = rd;
950 }
951 X(andcc_imm)
952 {
953 MODE_int_t rs1 = reg(ic->arg[0]), rs2 = (int32_t)ic->arg[1], rd;
954 rd = sparc_andcc32(cpu, rs1, rs2);
955 #ifndef MODE32
956 rd = sparc_andcc64(cpu, rs1, rs2);
957 #endif
958 reg(ic->arg[2]) = rd;
959 }
960
961
962 /*
963 * Subtract with ccr update:
964 *
965 * arg[0] = ptr to rs1
966 * arg[1] = ptr to rs2 or an immediate value (int32_t)
967 * arg[2] = ptr to rd
968 */
969 int32_t sparc_subcc32(struct cpu *cpu, int32_t rs1, int32_t rs2);
970 #ifdef MODE32
971 int32_t sparc_subcc32(struct cpu *cpu, int32_t rs1, int32_t rs2)
972 #else
973 int64_t sparc_subcc64(struct cpu *cpu, int64_t rs1, int64_t rs2)
974 #endif
975 {
976 int cc = 0, sign1 = 0, sign2 = 0, signd = 0, mask = SPARC_CCR_ICC_MASK;
977 MODE_int_t rd = rs1 - rs2;
978 if (rd == 0)
979 cc = SPARC_CCR_Z;
980 else if (rd < 0)
981 cc = SPARC_CCR_N, signd = 1;
982 if (rs1 < 0)
983 sign1 = 1;
984 if (rs2 < 0)
985 sign2 = 1;
986 if (sign1 != sign2 && sign1 != signd)
987 cc |= SPARC_CCR_V;
988 /* TODO: SPARC_CCR_C */
989 #ifndef MODE32
990 mask <<= SPARC_CCR_XCC_SHIFT;
991 cc <<= SPARC_CCR_XCC_SHIFT;
992 #endif
993 cpu->cd.sparc.ccr &= ~mask;
994 cpu->cd.sparc.ccr |= cc;
995 return rd;
996 }
997 X(subcc)
998 {
999 /* Like sub, but updates the ccr, and does both 32-bit and
1000 64-bit comparison at the same time. */
1001 MODE_int_t rs1 = reg(ic->arg[0]), rs2 = reg(ic->arg[1]), rd;
1002 rd = sparc_subcc32(cpu, rs1, rs2);
1003 #ifndef MODE32
1004 rd = sparc_subcc64(cpu, rs1, rs2);
1005 #endif
1006 reg(ic->arg[2]) = rd;
1007 }
1008 X(subcc_imm)
1009 {
1010 MODE_int_t rs1 = reg(ic->arg[0]), rs2 = (int32_t)ic->arg[1], rd;
1011 rd = sparc_subcc32(cpu, rs1, rs2);
1012 #ifndef MODE32
1013 rd = sparc_subcc64(cpu, rs1, rs2);
1014 #endif
1015 reg(ic->arg[2]) = rd;
1016 }
1017
1018
1019 #include "tmp_sparc_loadstore.c"
1020
1021
1022 /*
1023 * flushw: Flush Register Windows
1024 */
1025 X(flushw)
1026 {
1027 /* flushw acts as a nop, if cansave = nwindows - 2: */
1028 if (cpu->cd.sparc.cansave == cpu->cd.sparc.cpu_type.nwindows - 2)
1029 return;
1030
1031 /* TODO */
1032 fatal("flushw: TODO: cansave = %i\n", cpu->cd.sparc.cansave);
1033 exit(1);
1034 }
1035
1036
1037 /*
1038 * rd: Read special register
1039 *
1040 * arg[2] = ptr to rd
1041 */
1042 X(rd_psr)
1043 {
1044 reg(ic->arg[2]) = cpu->cd.sparc.psr;
1045 }
1046
1047
1048 /*
1049 * rdpr: Read privileged register
1050 *
1051 * arg[2] = ptr to rd
1052 */
1053 X(rdpr_tba)
1054 {
1055 reg(ic->arg[2]) = cpu->cd.sparc.tba;
1056 }
1057 X(rdpr_ver)
1058 {
1059 reg(ic->arg[2]) = cpu->cd.sparc.ver;
1060 }
1061
1062
1063 /*
1064 * wrpr: Write to privileged register
1065 *
1066 * arg[0] = ptr to rs1
1067 * arg[1] = ptr to rs2 or an immediate value (int32_t)
1068 */
1069 X(wrpr_tick)
1070 {
1071 cpu->cd.sparc.tick = (uint32_t) (reg(ic->arg[0]) ^ reg(ic->arg[1]));
1072 }
1073 X(wrpr_tick_imm)
1074 {
1075 cpu->cd.sparc.tick = (uint32_t) (reg(ic->arg[0]) ^ (int32_t)ic->arg[1]);
1076 }
1077 X(wrpr_pil)
1078 {
1079 cpu->cd.sparc.pil = (reg(ic->arg[0]) ^ reg(ic->arg[1]))
1080 & SPARC_PIL_MASK;
1081 }
1082 X(wrpr_pil_imm)
1083 {
1084 cpu->cd.sparc.pil = (reg(ic->arg[0]) ^ (int32_t)ic->arg[1])
1085 & SPARC_PIL_MASK;
1086 }
1087 X(wrpr_pstate)
1088 {
1089 sparc_update_pstate(cpu, reg(ic->arg[0]) ^ reg(ic->arg[1]));
1090 }
1091 X(wrpr_pstate_imm)
1092 {
1093 sparc_update_pstate(cpu, reg(ic->arg[0]) ^ (int32_t)ic->arg[1]);
1094 }
1095 X(wrpr_cleanwin)
1096 {
1097 cpu->cd.sparc.cleanwin = (uint32_t) (reg(ic->arg[0]) ^ reg(ic->arg[1]));
1098 }
1099 X(wrpr_cleanwin_imm)
1100 {
1101 cpu->cd.sparc.cleanwin =
1102 (uint32_t) (reg(ic->arg[0]) ^ (int32_t)ic->arg[1]);
1103 }
1104
1105
1106 /*****************************************************************************/
1107
1108
1109 X(end_of_page)
1110 {
1111 /* Update the PC: (offset 0, but on the next page) */
1112 cpu->pc &= ~((SPARC_IC_ENTRIES_PER_PAGE-1) <<
1113 SPARC_INSTR_ALIGNMENT_SHIFT);
1114 cpu->pc += (SPARC_IC_ENTRIES_PER_PAGE <<
1115 SPARC_INSTR_ALIGNMENT_SHIFT);
1116
1117 /* Find the new physical page and update the translation pointers: */
1118 quick_pc_to_pointers(cpu);
1119
1120 /* end_of_page doesn't count as an executed instruction: */
1121 cpu->n_translated_instrs --;
1122 }
1123
1124
1125 X(end_of_page2)
1126 {
1127 /* Synchronize PC on the _second_ instruction on the next page: */
1128 int low_pc = ((size_t)ic - (size_t)cpu->cd.sparc.cur_ic_page)
1129 / sizeof(struct sparc_instr_call);
1130 cpu->pc &= ~((SPARC_IC_ENTRIES_PER_PAGE-1)
1131 << SPARC_INSTR_ALIGNMENT_SHIFT);
1132 cpu->pc += (low_pc << SPARC_INSTR_ALIGNMENT_SHIFT);
1133
1134 /* This doesn't count as an executed instruction. */
1135 cpu->n_translated_instrs --;
1136
1137 quick_pc_to_pointers(cpu);
1138
1139 if (cpu->delay_slot == NOT_DELAYED)
1140 return;
1141
1142 fatal("end_of_page2: fatal error, we're in a delay slot\n");
1143 exit(1);
1144 }
1145
1146
1147 /*****************************************************************************/
1148
1149
1150 /*
1151 * sparc_instr_to_be_translated():
1152 *
1153 * Translate an instruction word into a sparc_instr_call. ic is filled in with
1154 * valid data for the translated instruction, or a "nothing" instruction if
1155 * there was a translation failure. The newly translated instruction is then
1156 * executed.
1157 */
1158 X(to_be_translated)
1159 {
1160 MODE_uint_t addr;
1161 int low_pc, in_crosspage_delayslot = 0;
1162 uint32_t iword;
1163 unsigned char *page;
1164 unsigned char ib[4];
1165 int main_opcode, op2, rd, rs1, rs2, btype, asi, cc, p, use_imm, x64 = 0;
1166 int store, signedness, size;
1167 int32_t tmpi32, siconst;
1168 /* void (*samepage_function)(struct cpu *, struct sparc_instr_call *);*/
1169
1170 /* Figure out the (virtual) address of the instruction: */
1171 low_pc = ((size_t)ic - (size_t)cpu->cd.sparc.cur_ic_page)
1172 / sizeof(struct sparc_instr_call);
1173
1174 /* Special case for branch with delayslot on the next page: */
1175 if (cpu->delay_slot == TO_BE_DELAYED && low_pc == 0) {
1176 /* fatal("[ delay-slot translation across page "
1177 "boundary ]\n"); */
1178 in_crosspage_delayslot = 1;
1179 }
1180
1181 addr = cpu->pc & ~((SPARC_IC_ENTRIES_PER_PAGE-1)
1182 << SPARC_INSTR_ALIGNMENT_SHIFT);
1183 addr += (low_pc << SPARC_INSTR_ALIGNMENT_SHIFT);
1184 cpu->pc = addr;
1185 addr &= ~((1 << SPARC_INSTR_ALIGNMENT_SHIFT) - 1);
1186
1187 /* Read the instruction word from memory: */
1188 #ifdef MODE32
1189 page = cpu->cd.sparc.host_load[addr >> 12];
1190 #else
1191 {
1192 const uint32_t mask1 = (1 << DYNTRANS_L1N) - 1;
1193 const uint32_t mask2 = (1 << DYNTRANS_L2N) - 1;
1194 const uint32_t mask3 = (1 << DYNTRANS_L3N) - 1;
1195 uint32_t x1 = (addr >> (64-DYNTRANS_L1N)) & mask1;
1196 uint32_t x2 = (addr >> (64-DYNTRANS_L1N-DYNTRANS_L2N)) & mask2;
1197 uint32_t x3 = (addr >> (64-DYNTRANS_L1N-DYNTRANS_L2N-
1198 DYNTRANS_L3N)) & mask3;
1199 struct DYNTRANS_L2_64_TABLE *l2 = cpu->cd.sparc.l1_64[x1];
1200 struct DYNTRANS_L3_64_TABLE *l3 = l2->l3[x2];
1201 page = l3->host_load[x3];
1202 }
1203 #endif
1204
1205 if (page != NULL) {
1206 /* fatal("TRANSLATION HIT!\n"); */
1207 memcpy(ib, page + (addr & 0xffc), sizeof(ib));
1208 } else {
1209 /* fatal("TRANSLATION MISS!\n"); */
1210 if (!cpu->memory_rw(cpu, cpu->mem, addr, ib,
1211 sizeof(ib), MEM_READ, CACHE_INSTRUCTION)) {
1212 fatal("to_be_translated(): "
1213 "read failed: TODO\n");
1214 goto bad;
1215 }
1216 }
1217
1218 /* SPARC instruction words are always big-endian. Convert
1219 to host order: */
1220 iword = BE32_TO_HOST( *((uint32_t *)&ib[0]) );
1221
1222
1223 #define DYNTRANS_TO_BE_TRANSLATED_HEAD
1224 #include "cpu_dyntrans.c"
1225 #undef DYNTRANS_TO_BE_TRANSLATED_HEAD
1226
1227
1228 /*
1229 * Translate the instruction:
1230 */
1231
1232 main_opcode = iword >> 30;
1233 rd = (iword >> 25) & 31;
1234 btype = rd & (N_SPARC_BRANCH_TYPES - 1);
1235 rs1 = (iword >> 14) & 31;
1236 use_imm = (iword >> 13) & 1;
1237 asi = (iword >> 5) & 0xff;
1238 rs2 = iword & 31;
1239 siconst = (int16_t)((iword & 0x1fff) << 3) >> 3;
1240 op2 = (main_opcode == 0)? ((iword >> 22) & 7) : ((iword >> 19) & 0x3f);
1241 cc = (iword >> 20) & 3;
1242 p = (iword >> 19) & 1;
1243
1244 switch (main_opcode) {
1245
1246 case 0: switch (op2) {
1247
1248 case 1: /* branch (icc or xcc) */
1249 tmpi32 = (iword << 13);
1250 tmpi32 >>= 11;
1251 ic->arg[0] = (int32_t)tmpi32 + (addr & 0xffc);
1252 /* rd contains the annul bit concatenated with 4 bits
1253 of condition code. cc=0 for icc, 2 for xcc: */
1254 /* TODO: samepage */
1255 switch (rd + (cc << 5)) {
1256 case 0x01: ic->f = instr(be); break;
1257 case 0x02: ic->f = instr(ble); break;
1258 case 0x03: ic->f = instr(bl); break;
1259 case 0x08: ic->f = instr(ba); break;
1260 case 0x09: ic->f = instr(bne); break;
1261 case 0x0a: ic->f = instr(bg); break;
1262 case 0x0b: ic->f = instr(bge); break;
1263 case 0x19: ic->f = instr(bne_a); break;
1264 case 0x41: ic->f = instr(be_xcc); break;
1265 case 0x42: ic->f = instr(ble_xcc);break;
1266 case 0x43: ic->f = instr(bl_xcc); break;
1267 case 0x48: ic->f = instr(ba); break;
1268 case 0x4a: ic->f = instr(bg_xcc); break;
1269 case 0x4b: ic->f = instr(bge_xcc);break;
1270 default:fatal("Unimplemented branch, 0x%x\n",
1271 rd + (cc<<5));
1272 goto bad;
1273 }
1274 break;
1275
1276 case 2: /* branch (32-bit integer comparison) */
1277 tmpi32 = (iword << 10);
1278 tmpi32 >>= 8;
1279 ic->arg[0] = (int32_t)tmpi32 + (addr & 0xffc);
1280 /* rd contains the annul bit concatenated with 4 bits
1281 of condition code: */
1282 /* TODO: samepage */
1283 switch (rd) {
1284 case 0x01: ic->f = instr(be); break;
1285 case 0x03: ic->f = instr(bl); break;
1286 case 0x08: ic->f = instr(ba); break;
1287 case 0x09: ic->f = instr(bne); break;
1288 case 0x0b: ic->f = instr(bge); break;
1289 default:fatal("Unimplemented branch rd=%i\n", rd);
1290 goto bad;
1291 }
1292 break;
1293
1294 case 3: /* branch on register, 64-bit integer comparison */
1295 tmpi32 = ((iword & 0x300000) >> 6) | (iword & 0x3fff);
1296 tmpi32 <<= 16;
1297 tmpi32 >>= 14;
1298 ic->arg[0] = (int32_t)tmpi32 + (addr & 0xffc);
1299 ic->arg[1] = (size_t)&cpu->cd.sparc.r[rs1];
1300 /* TODO: samepage */
1301 switch (btype) {
1302 case 0x05: ic->f = instr(brnz); break;
1303 default:fatal("Unimplemented branch 0x%x\n", rd);
1304 goto bad;
1305 }
1306 break;
1307
1308 case 4: /* sethi */
1309 ic->arg[0] = (size_t)&cpu->cd.sparc.r[rd];
1310 ic->arg[1] = (iword & 0x3fffff) << 10;
1311 ic->f = instr(set);
1312 if (rd == SPARC_ZEROREG)
1313 ic->f = instr(nop);
1314 break;
1315
1316 default:fatal("TODO: unimplemented op2=%i for main "
1317 "opcode %i\n", op2, main_opcode);
1318 goto bad;
1319 }
1320 break;
1321
1322 case 1: /* call and link */
1323 tmpi32 = (iword << 2);
1324 ic->arg[0] = (int32_t)tmpi32;
1325 ic->arg[1] = addr & 0xffc;
1326 if (cpu->machine->show_trace_tree)
1327 ic->f = instr(call_trace);
1328 else
1329 ic->f = instr(call);
1330 /* TODO: samepage */
1331 break;
1332
1333 case 2: switch (op2) {
1334
1335 case 0: /* add */
1336 case 1: /* and */
1337 case 2: /* or */
1338 case 3: /* xor */
1339 case 4: /* sub */
1340 case 5: /* andn */
1341 case 14:/* udiv */
1342 case 16:/* addcc */
1343 case 17:/* andcc */
1344 case 20:/* subcc (cmp) */
1345 case 37:/* sll */
1346 case 38:/* srl */
1347 case 39:/* sra */
1348 case 60:/* save */
1349 ic->arg[0] = (size_t)&cpu->cd.sparc.r[rs1];
1350 ic->f = NULL;
1351 if (use_imm) {
1352 ic->arg[1] = siconst;
1353 switch (op2) {
1354 case 0: ic->f = instr(add_imm); break;
1355 case 1: ic->f = instr(and_imm); break;
1356 case 2: ic->f = instr(or_imm); break;
1357 case 3: ic->f = instr(xor_imm); break;
1358 case 4: ic->f = instr(sub_imm); break;
1359 case 5: ic->f = instr(andn_imm); break;
1360 case 14:ic->f = instr(udiv_imm); break;
1361 case 16:ic->f = instr(addcc_imm); break;
1362 case 17:ic->f = instr(andcc_imm); break;
1363 case 20:ic->f = instr(subcc_imm); break;
1364 case 37:if (siconst & 0x1000) {
1365 ic->f = instr(sllx_imm);
1366 ic->arg[1] &= 63;
1367 x64 = 1;
1368 } else {
1369 ic->f = instr(sll_imm);
1370 ic->arg[1] &= 31;
1371 }
1372 break;
1373 case 38:if (siconst & 0x1000) {
1374 ic->f = instr(srlx_imm);
1375 ic->arg[1] &= 63;
1376 x64 = 1;
1377 } else {
1378 ic->f = instr(srl_imm);
1379 ic->arg[1] &= 31;
1380 }
1381 break;
1382 case 39:if (siconst & 0x1000) {
1383 ic->f = instr(srax_imm);
1384 ic->arg[1] &= 63;
1385 x64 = 1;
1386 } else {
1387 ic->f = instr(sra_imm);
1388 ic->arg[1] &= 31;
1389 }
1390 break;
1391 case 60:switch (cpu->cd.sparc.cpu_type.v) {
1392 case 9: ic->f = instr(save_v9_imm);
1393 break;
1394 default:fatal("only for v9 so far\n");
1395 goto bad;
1396 }
1397 }
1398 } else {
1399 ic->arg[1] = (size_t)&cpu->cd.sparc.r[rs2];
1400 switch (op2) {
1401 case 0: ic->f = instr(add); break;
1402 case 1: ic->f = instr(and); break;
1403 case 2: ic->f = instr(or); break;
1404 case 3: ic->f = instr(xor); break;
1405 case 4: ic->f = instr(sub); break;
1406 case 5: ic->f = instr(andn); break;
1407 case 14:ic->f = instr(udiv); break;
1408 case 16:ic->f = instr(addcc); break;
1409 case 17:ic->f = instr(andcc); break;
1410 case 20:ic->f = instr(subcc); break;
1411 case 37:if (siconst & 0x1000) {
1412 ic->f = instr(sllx);
1413 x64 = 1;
1414 } else
1415 ic->f = instr(sll);
1416 break;
1417 case 38:if (siconst & 0x1000) {
1418 ic->f = instr(srlx);
1419 x64 = 1;
1420 } else
1421 ic->f = instr(srl);
1422 break;
1423 case 39:if (siconst & 0x1000) {
1424 ic->f = instr(srax);
1425 x64 = 1;
1426 } else
1427 ic->f = instr(sra);
1428 break;
1429 }
1430 }
1431 if (ic->f == NULL) {
1432 fatal("TODO: Unimplemented instruction "
1433 "(possibly missed use_imm impl.)\n");
1434 goto bad;
1435 }
1436 ic->arg[2] = (size_t)&cpu->cd.sparc.r[rd];
1437 if (rd == SPARC_ZEROREG) {
1438 /*
1439 * Some opcodes should write to the scratch
1440 * register instead of becoming NOPs, when
1441 * rd is the zero register.
1442 *
1443 * Any opcode which updates the condition
1444 * codes, or anything which changes register
1445 * windows.
1446 */
1447 switch (op2) {
1448 case 16:/* addcc */
1449 case 17:/* andcc */
1450 case 20:/* subcc */
1451 case 60:/* save */
1452 ic->arg[2] = (size_t)
1453 &cpu->cd.sparc.scratch;
1454 break;
1455 default:ic->f = instr(nop);
1456 }
1457 }
1458 break;
1459
1460 case 41:/* rd %psr,%gpr on pre-sparcv9 */
1461 if (cpu->is_32bit) {
1462 ic->f = instr(rd_psr);
1463 ic->arg[2] = (size_t)&cpu->cd.sparc.r[rd];
1464 if (rd == SPARC_ZEROREG)
1465 ic->f = instr(nop);
1466 } else {
1467 fatal("opcode 2,41 not yet implemented"
1468 " for 64-bit cpus\n");
1469 goto bad;
1470 }
1471 break;
1472
1473 case 42:/* rdpr on sparcv9 */
1474 if (cpu->is_32bit) {
1475 fatal("opcode 2,42 not yet implemented"
1476 " for 32-bit cpus\n");
1477 goto bad;
1478 }
1479 ic->arg[2] = (size_t)&cpu->cd.sparc.r[rd];
1480 if (rd == SPARC_ZEROREG)
1481 ic->f = instr(nop);
1482 switch (rs1) {
1483 case 5: ic->f = instr(rdpr_tba); break;
1484 case 31: ic->f = instr(rdpr_ver); break;
1485 default:fatal("Unimplemented rs1=%i\n", rs1);
1486 goto bad;
1487 }
1488 break;
1489
1490 case 43:if (iword == 0x81580000) {
1491 ic->f = instr(flushw);
1492 } else {
1493 fatal("Unimplemented iword=0x%08"PRIx32"\n",
1494 iword);
1495 goto bad;
1496 }
1497 break;
1498
1499 case 48:/* wr (Note: works as xor) */
1500 ic->arg[0] = (size_t)&cpu->cd.sparc.r[rs1];
1501 if (use_imm) {
1502 ic->arg[1] = siconst;
1503 ic->f = instr(xor_imm);
1504 } else {
1505 ic->arg[1] = (size_t)&cpu->cd.sparc.r[rs2];
1506 ic->f = instr(xor);
1507 }
1508 ic->arg[2] = (size_t) NULL;
1509 switch (rd) {
1510 case 0: ic->arg[2] = (size_t)&cpu->cd.sparc.y;
1511 break;
1512 case 6: ic->arg[2] = (size_t)&cpu->cd.sparc.fprs;
1513 break;
1514 case 0x17:
1515 ic->arg[2] = (size_t)&cpu->cd.sparc.tick_cmpr;
1516 break;
1517 }
1518 if (ic->arg[2] == (size_t)NULL) {
1519 fatal("TODO: Unimplemented wr instruction, "
1520 "rd = 0x%02x\n", rd);
1521 goto bad;
1522 }
1523 break;
1524
1525 case 50:/* wrpr (Note: works as xor) */
1526 ic->arg[0] = (size_t)&cpu->cd.sparc.r[rs1];
1527 ic->f = NULL;
1528 if (use_imm) {
1529 ic->arg[1] = siconst;
1530 switch (rd) {
1531 case 4: ic->f = instr(wrpr_tick_imm); break;
1532 case 6: ic->f = instr(wrpr_pstate_imm); break;
1533 case 8: ic->f = instr(wrpr_pil_imm); break;
1534 case 12:ic->f = instr(wrpr_cleanwin_imm);break;
1535 }
1536 } else {
1537 ic->arg[1] = (size_t)&cpu->cd.sparc.r[rs2];
1538 switch (rd) {
1539 case 4: ic->f = instr(wrpr_tick); break;
1540 case 6: ic->f = instr(wrpr_pstate); break;
1541 case 8: ic->f = instr(wrpr_pil); break;
1542 case 12:ic->f = instr(wrpr_cleanwin); break;
1543 }
1544 }
1545 if (ic->f == NULL) {
1546 fatal("TODO: Unimplemented wrpr instruction,"
1547 " rd = 0x%02x\n", rd);
1548 goto bad;
1549 }
1550 break;
1551
1552 case 56:/* jump and link */
1553 ic->arg[0] = (size_t)&cpu->cd.sparc.r[rs1];
1554 ic->arg[2] = (size_t)&cpu->cd.sparc.r[rd];
1555 if (rd == SPARC_ZEROREG)
1556 ic->arg[2] = (size_t)&cpu->cd.sparc.scratch;
1557
1558 if (use_imm) {
1559 ic->arg[1] = siconst;
1560 if (rd == SPARC_ZEROREG)
1561 ic->f = instr(jmpl_imm_no_rd);
1562 else
1563 ic->f = instr(jmpl_imm);
1564 } else {
1565 ic->arg[1] = (size_t)&cpu->cd.sparc.r[rs2];
1566 if (rd == SPARC_ZEROREG)
1567 ic->f = instr(jmpl_reg_no_rd);
1568 else
1569 ic->f = instr(jmpl_reg);
1570 }
1571
1572 /* special trace case: */
1573 if (cpu->machine->show_trace_tree) {
1574 if (iword == 0x81c3e008)
1575 ic->f = instr(retl_trace);
1576 else {
1577 if (use_imm)
1578 ic->f = instr(jmpl_imm_trace);
1579 else
1580 ic->f = instr(jmpl_reg_trace);
1581 }
1582 }
1583 break;
1584
1585 case 57:/* return */
1586 ic->arg[0] = (size_t)&cpu->cd.sparc.r[rs1];
1587
1588 if (use_imm) {
1589 ic->arg[1] = siconst;
1590 ic->f = instr(return_imm);
1591 } else {
1592 ic->arg[1] = (size_t)&cpu->cd.sparc.r[rs2];
1593 ic->f = instr(return_reg);
1594 }
1595
1596 /* special trace case: */
1597 if (cpu->machine->show_trace_tree) {
1598 if (use_imm)
1599 ic->f = instr(return_imm_trace);
1600 else
1601 ic->f = instr(return_reg_trace);
1602 }
1603 break;
1604
1605 default:fatal("TODO: unimplemented op2=%i for main "
1606 "opcode %i\n", op2, main_opcode);
1607 goto bad;
1608 }
1609 break;
1610
1611 case 3: switch (op2) {
1612
1613 case 0:/* lduw */
1614 case 1:/* ldub */
1615 case 2:/* lduh */
1616 case 4:/* st(w) */
1617 case 5:/* stb */
1618 case 6:/* sth */
1619 case 8:/* ldsw */
1620 case 9:/* ldsb */
1621 case 10:/* ldsh */
1622 case 11:/* ldx */
1623 case 14:/* stx */
1624 store = 1; signedness = 0; size = 3;
1625 switch (op2) {
1626 case 0: /* lduw */ store=0; size=2; break;
1627 case 1: /* ldub */ store=0; size=0; break;
1628 case 2: /* lduh */ store=0; size=1; break;
1629 case 4: /* st */ size = 2; break;
1630 case 5: /* stb */ size = 0; break;
1631 case 6: /* sth */ size = 1; break;
1632 case 8: /* ldsw */ store=0; size=2; signedness=1;
1633 break;
1634 case 9: /* ldsb */ store=0; size=0; signedness=1;
1635 break;
1636 case 10: /* ldsh */ store=0; size=1; signedness=1;
1637 break;
1638 case 11: /* ldx */ store=0; break;
1639 case 14: /* stx */ break;
1640 }
1641 ic->f =
1642 #ifdef MODE32
1643 sparc32_loadstore
1644 #else
1645 sparc_loadstore
1646 #endif
1647 [ use_imm*16 + store*8 + size*2 + signedness ];
1648
1649 ic->arg[0] = (size_t)&cpu->cd.sparc.r[rd];
1650 ic->arg[1] = (size_t)&cpu->cd.sparc.r[rs1];
1651 if (use_imm)
1652 ic->arg[2] = siconst;
1653 else
1654 ic->arg[2] = (size_t)&cpu->cd.sparc.r[rs2];
1655
1656 if (!store && rd == SPARC_ZEROREG)
1657 ic->arg[0] = (size_t)&cpu->cd.sparc.scratch;
1658
1659 break;
1660
1661 default:fatal("TODO: unimplemented op2=%i for main "
1662 "opcode %i\n", op2, main_opcode);
1663 goto bad;
1664 }
1665 break;
1666
1667 }
1668
1669
1670 if (x64 && cpu->is_32bit) {
1671 fatal("TODO: 64-bit instr on 32-bit cpu\n");
1672 goto bad;
1673 }
1674
1675
1676 #define DYNTRANS_TO_BE_TRANSLATED_TAIL
1677 #include "cpu_dyntrans.c"
1678 #undef DYNTRANS_TO_BE_TRANSLATED_TAIL
1679 }
1680

  ViewVC Help
Powered by ViewVC 1.1.26