/[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 30 - (show annotations)
Mon Oct 8 16:20:40 2007 UTC (16 years, 5 months ago) by dpavlin
File MIME type: text/plain
File size: 39133 byte(s)
++ trunk/HISTORY	(local)
$Id: HISTORY,v 1.1325 2006/08/15 15:38:37 debug Exp $
20060723	More Transputer instructions (pfix, nfix, opr, mint, ldl, ldlp,
		eqc, rev, ajw, stl, stlf, sthf, sub, ldnl, ldnlp, ldpi, move,
		wcnt, add, bcnt).
		Adding more SPARC instructions (andcc, addcc, bl, rdpr).
		Progress on the igsfb framebuffer used by NetBSD/netwinder.
		Enabling 8-bit fills in dev_fb.
		NetBSD/netwinder 3.0.1 can now run from a disk image :-)
20060724	Cleanup/performance fix for 64-bit virtual translation table
		updates (by removing the "timestamp" stuff). A full NetBSD/pmax
		3.0.1 install for R4400 has dropped from 667 seconds to 584 :)
		Fixing the igsfb "almost vga" color (it is 24-bit, not 18-bit).
		Adding some MIPS instruction combinations (3*lw, and 3*addu).
		The 8048 keyboard now turns off interrupt enable between the
		KBR_ACK and the KBR_RSTDONE, to work better with Linux 2.6.
		Not causing PPC DEC interrupts if PPC_NO_DEC is set for a
		specific CPU; NetBSD/bebox gets slightly further than before.
		Adding some more SPARC instructions: branches, udiv.
20060725	Refreshing dev_pckbc.c a little.
		Cleanups for the SH emulation mode, and adding the first
		"compact" (16-bit) instructions: various simple movs, nop,
		shll, stc, or, ldc.
20060726	Adding dummy "pcn" (AMD PCnet NIC) PCI glue.
20060727	Various cleanups; removing stuff from cpu.h, such as
		running_translated (not really meaningful anymore), and
		page flags (breaking into the debugger clears all translations
		anyway).
		Minor MIPS instruction combination updates.
20060807	Expanding the 3*sw and 3*lw MIPS instruction combinations to
		work with 2* and 4* too, resulting in a minor performance gain.
		Implementing a usleep hack for the RM52xx/MIPS32/MIPS64 "wait"
		instruction (when emulating 1 cpu).
20060808	Experimenting with some more MIPS instruction combinations.
		Implementing support for showing a (hardcoded 12x22) text
		cursor in igsfb.
20060809	Simplifying the NetBSD/evbmips (Malta) install instructions
		somewhat (by using a NetBSD/pmax ramdisk install kernel).
20060812	Experimenting more with the MIPS 'wait' instruction.
		PCI configuration register writes can now be handled, which
		allow PCI IDE controllers to work with NetBSD/Malta 3.0.1 and
		NetBSD/cobalt 3.0.1. (Previously only NetBSD 2.1 worked.)
20060813	Updating dev_gt.c based on numbers from Alec Voropay, to enable
		Linux 2.6 to use PCI on Malta.
		Continuing on Algor interrupt stuff.
20060814	Adding support for routing ISA interrupts to two different
		interrupts, making it possible to run NetBSD/algor :-)
20060814-15	Testing for the release.

==============  RELEASE 0.4.2  ==============


1 /*
2 * Copyright (C) 2005-2006 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.23 2006/07/24 22:32:44 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 * bne
159 *
160 * arg[0] = int32_t displacement compared to the start of the current page
161 */
162 X(bne)
163 {
164 MODE_uint_t old_pc = cpu->pc;
165 int cond = (cpu->cd.sparc.ccr & SPARC_CCR_Z) ? 0 : 1;
166 cpu->delay_slot = TO_BE_DELAYED;
167 ic[1].f(cpu, ic+1);
168 cpu->n_translated_instrs ++;
169 if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
170 /* Note: Must be non-delayed when jumping to the new pc: */
171 cpu->delay_slot = NOT_DELAYED;
172 if (cond) {
173 old_pc &= ~((SPARC_IC_ENTRIES_PER_PAGE - 1)
174 << SPARC_INSTR_ALIGNMENT_SHIFT);
175 cpu->pc = old_pc + (int32_t)ic->arg[0];
176 quick_pc_to_pointers(cpu);
177 }
178 } else
179 cpu->delay_slot = NOT_DELAYED;
180 }
181 X(bne_a)
182 {
183 MODE_uint_t old_pc = cpu->pc;
184 int cond = (cpu->cd.sparc.ccr & SPARC_CCR_Z) ? 0 : 1;
185 cpu->delay_slot = TO_BE_DELAYED;
186 if (!cond) {
187 /* Nullify the delay slot: */
188 cpu->cd.sparc.next_ic ++;
189 return;
190 }
191 ic[1].f(cpu, ic+1);
192 cpu->n_translated_instrs ++;
193 if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
194 /* Note: Must be non-delayed when jumping to the new pc: */
195 cpu->delay_slot = NOT_DELAYED;
196 old_pc &= ~((SPARC_IC_ENTRIES_PER_PAGE - 1)
197 << SPARC_INSTR_ALIGNMENT_SHIFT);
198 cpu->pc = old_pc + (int32_t)ic->arg[0];
199 quick_pc_to_pointers(cpu);
200 } else
201 cpu->delay_slot = NOT_DELAYED;
202 }
203
204
205 /*
206 * bg
207 *
208 * arg[0] = int32_t displacement compared to the start of the current page
209 */
210 X(bg)
211 {
212 MODE_uint_t old_pc = cpu->pc;
213 int n = (cpu->cd.sparc.ccr & SPARC_CCR_N) ? 1 : 0;
214 int v = (cpu->cd.sparc.ccr & SPARC_CCR_V) ? 1 : 0;
215 int z = (cpu->cd.sparc.ccr & SPARC_CCR_Z) ? 1 : 0;
216 int cond = !(z | (n ^ v));
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(bg_xcc)
233 {
234 MODE_uint_t old_pc = cpu->pc;
235 int n = ((cpu->cd.sparc.ccr >> SPARC_CCR_XCC_SHIFT) & SPARC_CCR_N)? 1:0;
236 int v = ((cpu->cd.sparc.ccr >> SPARC_CCR_XCC_SHIFT) & SPARC_CCR_V)? 1:0;
237 int z = ((cpu->cd.sparc.ccr >> SPARC_CCR_XCC_SHIFT) & SPARC_CCR_Z)? 1:0;
238 int cond = !(z | (n ^ v));
239 cpu->delay_slot = TO_BE_DELAYED;
240 ic[1].f(cpu, ic+1);
241 cpu->n_translated_instrs ++;
242 if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
243 /* Note: Must be non-delayed when jumping to the new pc: */
244 cpu->delay_slot = NOT_DELAYED;
245 if (cond) {
246 old_pc &= ~((SPARC_IC_ENTRIES_PER_PAGE - 1)
247 << SPARC_INSTR_ALIGNMENT_SHIFT);
248 cpu->pc = old_pc + (int32_t)ic->arg[0];
249 quick_pc_to_pointers(cpu);
250 }
251 } else
252 cpu->delay_slot = NOT_DELAYED;
253 }
254
255
256 /*
257 * bge
258 *
259 * arg[0] = int32_t displacement compared to the start of the current page
260 */
261 X(bge)
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 cond = !(n ^ v);
267 cpu->delay_slot = TO_BE_DELAYED;
268 ic[1].f(cpu, ic+1);
269 cpu->n_translated_instrs ++;
270 if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
271 /* Note: Must be non-delayed when jumping to the new pc: */
272 cpu->delay_slot = NOT_DELAYED;
273 if (cond) {
274 old_pc &= ~((SPARC_IC_ENTRIES_PER_PAGE - 1)
275 << SPARC_INSTR_ALIGNMENT_SHIFT);
276 cpu->pc = old_pc + (int32_t)ic->arg[0];
277 quick_pc_to_pointers(cpu);
278 }
279 } else
280 cpu->delay_slot = NOT_DELAYED;
281 }
282 X(bge_xcc)
283 {
284 MODE_uint_t old_pc = cpu->pc;
285 int n = ((cpu->cd.sparc.ccr >> SPARC_CCR_XCC_SHIFT) & SPARC_CCR_N)? 1:0;
286 int v = ((cpu->cd.sparc.ccr >> SPARC_CCR_XCC_SHIFT) & SPARC_CCR_V)? 1:0;
287 int cond = !(n ^ v);
288 cpu->delay_slot = TO_BE_DELAYED;
289 ic[1].f(cpu, ic+1);
290 cpu->n_translated_instrs ++;
291 if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
292 /* Note: Must be non-delayed when jumping to the new pc: */
293 cpu->delay_slot = NOT_DELAYED;
294 if (cond) {
295 old_pc &= ~((SPARC_IC_ENTRIES_PER_PAGE - 1)
296 << SPARC_INSTR_ALIGNMENT_SHIFT);
297 cpu->pc = old_pc + (int32_t)ic->arg[0];
298 quick_pc_to_pointers(cpu);
299 }
300 } else
301 cpu->delay_slot = NOT_DELAYED;
302 }
303
304
305 /*
306 * be
307 *
308 * arg[0] = int32_t displacement compared to the start of the current page
309 */
310 X(be)
311 {
312 MODE_uint_t old_pc = cpu->pc;
313 int cond = cpu->cd.sparc.ccr & SPARC_CCR_Z;
314 cpu->delay_slot = TO_BE_DELAYED;
315 ic[1].f(cpu, ic+1);
316 cpu->n_translated_instrs ++;
317 if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
318 /* Note: Must be non-delayed when jumping to the new pc: */
319 cpu->delay_slot = NOT_DELAYED;
320 if (cond) {
321 old_pc &= ~((SPARC_IC_ENTRIES_PER_PAGE - 1)
322 << SPARC_INSTR_ALIGNMENT_SHIFT);
323 cpu->pc = old_pc + (int32_t)ic->arg[0];
324 quick_pc_to_pointers(cpu);
325 }
326 } else
327 cpu->delay_slot = NOT_DELAYED;
328 }
329 X(be_xcc)
330 {
331 MODE_uint_t old_pc = cpu->pc;
332 int cond = (cpu->cd.sparc.ccr >> SPARC_CCR_XCC_SHIFT) & SPARC_CCR_Z;
333 cpu->delay_slot = TO_BE_DELAYED;
334 ic[1].f(cpu, ic+1);
335 cpu->n_translated_instrs ++;
336 if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
337 /* Note: Must be non-delayed when jumping to the new pc: */
338 cpu->delay_slot = NOT_DELAYED;
339 if (cond) {
340 old_pc &= ~((SPARC_IC_ENTRIES_PER_PAGE - 1)
341 << SPARC_INSTR_ALIGNMENT_SHIFT);
342 cpu->pc = old_pc + (int32_t)ic->arg[0];
343 quick_pc_to_pointers(cpu);
344 }
345 } else
346 cpu->delay_slot = NOT_DELAYED;
347 }
348
349
350 /*
351 * ba
352 *
353 * arg[0] = int32_t displacement compared to the start of the current page
354 */
355 X(ba)
356 {
357 MODE_uint_t old_pc = cpu->pc;
358 cpu->delay_slot = TO_BE_DELAYED;
359 ic[1].f(cpu, ic+1);
360 cpu->n_translated_instrs ++;
361 if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
362 /* Note: Must be non-delayed when jumping to the new pc: */
363 cpu->delay_slot = NOT_DELAYED;
364 old_pc &= ~((SPARC_IC_ENTRIES_PER_PAGE - 1)
365 << SPARC_INSTR_ALIGNMENT_SHIFT);
366 cpu->pc = old_pc + (int32_t)ic->arg[0];
367 quick_pc_to_pointers(cpu);
368 } else
369 cpu->delay_slot = NOT_DELAYED;
370 }
371
372
373 /*
374 * brnz
375 *
376 * arg[0] = int32_t displacement compared to the start of the current page
377 * arg[1] = ptr to rs1
378 */
379 X(brnz)
380 {
381 MODE_uint_t old_pc = cpu->pc;
382 int cond = reg(ic->arg[1]) != 0;
383 cpu->delay_slot = TO_BE_DELAYED;
384 ic[1].f(cpu, ic+1);
385 cpu->n_translated_instrs ++;
386 if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
387 /* Note: Must be non-delayed when jumping to the new pc: */
388 cpu->delay_slot = NOT_DELAYED;
389 if (cond) {
390 old_pc &= ~((SPARC_IC_ENTRIES_PER_PAGE - 1)
391 << SPARC_INSTR_ALIGNMENT_SHIFT);
392 cpu->pc = old_pc + (int32_t)ic->arg[0];
393 quick_pc_to_pointers(cpu);
394 }
395 } else
396 cpu->delay_slot = NOT_DELAYED;
397 }
398
399
400 /*
401 * Jump and link
402 *
403 * arg[0] = ptr to rs1
404 * arg[1] = ptr to rs2 or an immediate value (int32_t)
405 * arg[2] = ptr to rd
406 */
407 X(jmpl_imm)
408 {
409 int low_pc = ((size_t)ic - (size_t)cpu->cd.sparc.cur_ic_page)
410 / sizeof(struct sparc_instr_call);
411 cpu->pc &= ~((SPARC_IC_ENTRIES_PER_PAGE-1)
412 << SPARC_INSTR_ALIGNMENT_SHIFT);
413 cpu->pc += (low_pc << SPARC_INSTR_ALIGNMENT_SHIFT);
414 reg(ic->arg[2]) = cpu->pc;
415
416 cpu->delay_slot = TO_BE_DELAYED;
417 ic[1].f(cpu, ic+1);
418 cpu->n_translated_instrs ++;
419
420 if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
421 /* Note: Must be non-delayed when jumping to the new pc: */
422 cpu->delay_slot = NOT_DELAYED;
423 cpu->pc = reg(ic->arg[0]) + (int32_t)ic->arg[1];
424 quick_pc_to_pointers(cpu);
425 } else
426 cpu->delay_slot = NOT_DELAYED;
427 }
428 X(jmpl_imm_no_rd)
429 {
430 int low_pc = ((size_t)ic - (size_t)cpu->cd.sparc.cur_ic_page)
431 / sizeof(struct sparc_instr_call);
432 cpu->pc &= ~((SPARC_IC_ENTRIES_PER_PAGE-1)
433 << SPARC_INSTR_ALIGNMENT_SHIFT);
434 cpu->pc += (low_pc << SPARC_INSTR_ALIGNMENT_SHIFT);
435
436 cpu->delay_slot = TO_BE_DELAYED;
437 ic[1].f(cpu, ic+1);
438 cpu->n_translated_instrs ++;
439
440 if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
441 /* Note: Must be non-delayed when jumping to the new pc: */
442 cpu->delay_slot = NOT_DELAYED;
443 cpu->pc = reg(ic->arg[0]) + (int32_t)ic->arg[1];
444 quick_pc_to_pointers(cpu);
445 } else
446 cpu->delay_slot = NOT_DELAYED;
447 }
448 X(jmpl_reg)
449 {
450 int low_pc = ((size_t)ic - (size_t)cpu->cd.sparc.cur_ic_page)
451 / sizeof(struct sparc_instr_call);
452 cpu->pc &= ~((SPARC_IC_ENTRIES_PER_PAGE-1)
453 << SPARC_INSTR_ALIGNMENT_SHIFT);
454 cpu->pc += (low_pc << SPARC_INSTR_ALIGNMENT_SHIFT);
455 reg(ic->arg[2]) = cpu->pc;
456
457 cpu->delay_slot = TO_BE_DELAYED;
458 ic[1].f(cpu, ic+1);
459 cpu->n_translated_instrs ++;
460
461 if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
462 /* Note: Must be non-delayed when jumping to the new pc: */
463 cpu->delay_slot = NOT_DELAYED;
464 cpu->pc = reg(ic->arg[0]) + reg(ic->arg[1]);
465 quick_pc_to_pointers(cpu);
466 } else
467 cpu->delay_slot = NOT_DELAYED;
468 }
469 X(jmpl_reg_no_rd)
470 {
471 int low_pc = ((size_t)ic - (size_t)cpu->cd.sparc.cur_ic_page)
472 / sizeof(struct sparc_instr_call);
473 cpu->pc &= ~((SPARC_IC_ENTRIES_PER_PAGE-1)
474 << SPARC_INSTR_ALIGNMENT_SHIFT);
475 cpu->pc += (low_pc << SPARC_INSTR_ALIGNMENT_SHIFT);
476
477 cpu->delay_slot = TO_BE_DELAYED;
478 ic[1].f(cpu, ic+1);
479 cpu->n_translated_instrs ++;
480
481 if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
482 /* Note: Must be non-delayed when jumping to the new pc: */
483 cpu->delay_slot = NOT_DELAYED;
484 cpu->pc = reg(ic->arg[0]) + reg(ic->arg[1]);
485 quick_pc_to_pointers(cpu);
486 } else
487 cpu->delay_slot = NOT_DELAYED;
488 }
489
490
491 X(jmpl_imm_trace)
492 {
493 int low_pc = ((size_t)ic - (size_t)cpu->cd.sparc.cur_ic_page)
494 / sizeof(struct sparc_instr_call);
495 cpu->pc &= ~((SPARC_IC_ENTRIES_PER_PAGE-1)
496 << SPARC_INSTR_ALIGNMENT_SHIFT);
497 cpu->pc += (low_pc << SPARC_INSTR_ALIGNMENT_SHIFT);
498 reg(ic->arg[2]) = cpu->pc;
499
500 cpu->delay_slot = TO_BE_DELAYED;
501 ic[1].f(cpu, ic+1);
502 cpu->n_translated_instrs ++;
503
504 if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
505 /* Note: Must be non-delayed when jumping to the new pc: */
506 cpu->delay_slot = NOT_DELAYED;
507 cpu->pc = reg(ic->arg[0]) + (int32_t)ic->arg[1];
508 cpu_functioncall_trace(cpu, cpu->pc);
509 quick_pc_to_pointers(cpu);
510 } else
511 cpu->delay_slot = NOT_DELAYED;
512 }
513 X(jmpl_reg_trace)
514 {
515 int low_pc = ((size_t)ic - (size_t)cpu->cd.sparc.cur_ic_page)
516 / sizeof(struct sparc_instr_call);
517 cpu->pc &= ~((SPARC_IC_ENTRIES_PER_PAGE-1)
518 << SPARC_INSTR_ALIGNMENT_SHIFT);
519 cpu->pc += (low_pc << SPARC_INSTR_ALIGNMENT_SHIFT);
520 reg(ic->arg[2]) = cpu->pc;
521
522 cpu->delay_slot = TO_BE_DELAYED;
523 ic[1].f(cpu, ic+1);
524 cpu->n_translated_instrs ++;
525
526 if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
527 /* Note: Must be non-delayed when jumping to the new pc: */
528 cpu->delay_slot = NOT_DELAYED;
529 cpu->pc = reg(ic->arg[0]) + reg(ic->arg[1]);
530 cpu_functioncall_trace(cpu, cpu->pc);
531 quick_pc_to_pointers(cpu);
532 } else
533 cpu->delay_slot = NOT_DELAYED;
534 }
535 X(retl_trace)
536 {
537 int low_pc = ((size_t)ic - (size_t)cpu->cd.sparc.cur_ic_page)
538 / sizeof(struct sparc_instr_call);
539 cpu->pc &= ~((SPARC_IC_ENTRIES_PER_PAGE-1)
540 << SPARC_INSTR_ALIGNMENT_SHIFT);
541 cpu->pc += (low_pc << SPARC_INSTR_ALIGNMENT_SHIFT);
542
543 cpu->delay_slot = TO_BE_DELAYED;
544 ic[1].f(cpu, ic+1);
545 cpu->n_translated_instrs ++;
546
547 if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
548 /* Note: Must be non-delayed when jumping to the new pc: */
549 cpu->delay_slot = NOT_DELAYED;
550 cpu->pc = reg(ic->arg[0]) + (int32_t)ic->arg[1];
551 quick_pc_to_pointers(cpu);
552 cpu_functioncall_trace_return(cpu);
553 } else
554 cpu->delay_slot = NOT_DELAYED;
555 }
556
557
558 /*
559 * set: Set a register to a value (e.g. sethi).
560 *
561 * arg[0] = ptr to rd
562 * arg[1] = value (uint32_t)
563 */
564 X(set)
565 {
566 reg(ic->arg[0]) = (uint32_t)ic->arg[1];
567 }
568
569
570 /*
571 * Computational/arithmetic instructions:
572 *
573 * arg[0] = ptr to rs1
574 * arg[1] = ptr to rs2 or an immediate value (int32_t)
575 * arg[2] = ptr to rd
576 */
577 X(add) { reg(ic->arg[2]) = reg(ic->arg[0]) + reg(ic->arg[1]); }
578 X(add_imm) { reg(ic->arg[2]) = reg(ic->arg[0]) + (int32_t)ic->arg[1]; }
579 X(and) { reg(ic->arg[2]) = reg(ic->arg[0]) & reg(ic->arg[1]); }
580 X(and_imm) { reg(ic->arg[2]) = reg(ic->arg[0]) & (int32_t)ic->arg[1]; }
581 X(or) { reg(ic->arg[2]) = reg(ic->arg[0]) | reg(ic->arg[1]); }
582 X(or_imm) { reg(ic->arg[2]) = reg(ic->arg[0]) | (int32_t)ic->arg[1]; }
583 X(xor) { reg(ic->arg[2]) = reg(ic->arg[0]) ^ reg(ic->arg[1]); }
584 X(xor_imm) { reg(ic->arg[2]) = reg(ic->arg[0]) ^ (int32_t)ic->arg[1]; }
585 X(sub) { reg(ic->arg[2]) = reg(ic->arg[0]) - reg(ic->arg[1]); }
586 X(sub_imm) { reg(ic->arg[2]) = reg(ic->arg[0]) - (int32_t)ic->arg[1]; }
587
588 X(sll) { reg(ic->arg[2]) = (uint32_t)reg(ic->arg[0]) <<
589 (reg(ic->arg[1]) & 31); }
590 X(sllx) { reg(ic->arg[2]) = (uint64_t)reg(ic->arg[0]) <<
591 (reg(ic->arg[1]) & 63); }
592 X(sll_imm) { reg(ic->arg[2]) = (uint32_t)reg(ic->arg[0]) << ic->arg[1]; }
593 X(sllx_imm) { reg(ic->arg[2]) = (uint64_t)reg(ic->arg[0]) << ic->arg[1]; }
594
595 X(srl) { reg(ic->arg[2]) = (uint32_t)reg(ic->arg[0]) >>
596 (reg(ic->arg[1]) & 31); }
597 X(srlx) { reg(ic->arg[2]) = (uint64_t)reg(ic->arg[0]) >>
598 (reg(ic->arg[1]) & 63); }
599 X(srl_imm) { reg(ic->arg[2]) = (uint32_t)reg(ic->arg[0]) >> ic->arg[1]; }
600 X(srlx_imm) { reg(ic->arg[2]) = (uint64_t)reg(ic->arg[0]) >> ic->arg[1]; }
601
602 X(sra) { reg(ic->arg[2]) = (int32_t)reg(ic->arg[0]) >>
603 (reg(ic->arg[1]) & 31); }
604 X(srax) { reg(ic->arg[2]) = (int64_t)reg(ic->arg[0]) >>
605 (reg(ic->arg[1]) & 63); }
606 X(sra_imm) { reg(ic->arg[2]) = (int32_t)reg(ic->arg[0]) >> ic->arg[1]; }
607 X(srax_imm) { reg(ic->arg[2]) = (int64_t)reg(ic->arg[0]) >> ic->arg[1]; }
608
609 X(udiv)
610 {
611 uint64_t z = (cpu->cd.sparc.y << 32) | (uint32_t)reg(ic->arg[0]);
612 z /= (uint32_t)reg(ic->arg[1]);
613 if (z > 0xffffffff)
614 z = 0xffffffff;
615 reg(ic->arg[2]) = z;
616 }
617 X(udiv_imm)
618 {
619 uint64_t z = (cpu->cd.sparc.y << 32) | (uint32_t)reg(ic->arg[0]);
620 z /= (uint32_t)ic->arg[1];
621 if (z > 0xffffffff)
622 z = 0xffffffff;
623 reg(ic->arg[2]) = z;
624 }
625
626
627 /*
628 * Save:
629 *
630 * arg[0] = ptr to rs1
631 * arg[1] = ptr to rs2 or an immediate value (int32_t)
632 * arg[2] = ptr to rd (_after_ the register window change)
633 */
634 X(save_v9_imm)
635 {
636 MODE_uint_t rs = reg(ic->arg[0]) + (int32_t)ic->arg[1];
637 int cwp = cpu->cd.sparc.cwp;
638
639 if (cpu->cd.sparc.cansave == 0) {
640 fatal("save_v9_imm: spill trap. TODO\n");
641 exit(1);
642 }
643
644 if (cpu->cd.sparc.cleanwin - cpu->cd.sparc.canrestore == 0) {
645 fatal("save_v9_imm: clean_window trap. TODO\n");
646 exit(1);
647 }
648
649 /* Save away old in registers: */
650 memcpy(&cpu->cd.sparc.r_inout[cwp][0], &cpu->cd.sparc.r[SPARC_REG_I0],
651 sizeof(cpu->cd.sparc.r[SPARC_REG_I0]) * N_SPARC_INOUT_REG);
652
653 /* Save away old local registers: */
654 memcpy(&cpu->cd.sparc.r_local[cwp][0], &cpu->cd.sparc.r[SPARC_REG_L0],
655 sizeof(cpu->cd.sparc.r[SPARC_REG_L0]) * N_SPARC_INOUT_REG);
656
657 cwp = cpu->cd.sparc.cwp = (cwp + 1) % cpu->cd.sparc.cpu_type.nwindows;
658 cpu->cd.sparc.cansave --;
659 cpu->cd.sparc.canrestore ++; /* TODO: modulo here too? */
660
661 /* The out registers become the new in registers: */
662 memcpy(&cpu->cd.sparc.r[SPARC_REG_I0], &cpu->cd.sparc.r[SPARC_REG_O0],
663 sizeof(cpu->cd.sparc.r[SPARC_REG_O0]) * N_SPARC_INOUT_REG);
664
665 /* Read new local registers: */
666 memcpy(&cpu->cd.sparc.r[SPARC_REG_L0], &cpu->cd.sparc.r_local[cwp][0],
667 sizeof(cpu->cd.sparc.r[SPARC_REG_L0]) * N_SPARC_INOUT_REG);
668
669 reg(ic->arg[2]) = rs;
670 }
671
672
673 /*
674 * Add with ccr update:
675 *
676 * arg[0] = ptr to rs1
677 * arg[1] = ptr to rs2 or an immediate value (int32_t)
678 * arg[2] = ptr to rd
679 */
680 int32_t sparc_addcc32(struct cpu *cpu, int32_t rs1, int32_t rs2);
681 #ifdef MODE32
682 int32_t sparc_addcc32(struct cpu *cpu, int32_t rs1, int32_t rs2)
683 #else
684 int64_t sparc_addcc64(struct cpu *cpu, int64_t rs1, int64_t rs2)
685 #endif
686 {
687 int cc = 0, sign1 = 0, sign2 = 0, signd = 0, mask = SPARC_CCR_ICC_MASK;
688 MODE_int_t rd = rs1 + rs2;
689 if (rd == 0)
690 cc = SPARC_CCR_Z;
691 else if (rd < 0)
692 cc = SPARC_CCR_N, signd = 1;
693 if (rs1 < 0)
694 sign1 = 1;
695 if (rs2 < 0)
696 sign2 = 1;
697 if (sign1 == sign2 && sign1 != signd)
698 cc |= SPARC_CCR_V;
699 /* TODO: SPARC_CCR_C */
700 #ifndef MODE32
701 mask <<= SPARC_CCR_XCC_SHIFT;
702 cc <<= SPARC_CCR_XCC_SHIFT;
703 #endif
704 cpu->cd.sparc.ccr &= ~mask;
705 cpu->cd.sparc.ccr |= cc;
706 return rd;
707 }
708 X(addcc)
709 {
710 /* Like add, but updates the ccr, and does both 32-bit and
711 64-bit comparison at the same time. */
712 MODE_int_t rs1 = reg(ic->arg[0]), rs2 = reg(ic->arg[1]), rd;
713 rd = sparc_addcc32(cpu, rs1, rs2);
714 #ifndef MODE32
715 rd = sparc_addcc64(cpu, rs1, rs2);
716 #endif
717 reg(ic->arg[2]) = rd;
718 }
719 X(addcc_imm)
720 {
721 MODE_int_t rs1 = reg(ic->arg[0]), rs2 = (int32_t)ic->arg[1], rd;
722 rd = sparc_addcc32(cpu, rs1, rs2);
723 #ifndef MODE32
724 rd = sparc_addcc64(cpu, rs1, rs2);
725 #endif
726 reg(ic->arg[2]) = rd;
727 }
728
729
730 /*
731 * And with ccr update:
732 *
733 * arg[0] = ptr to rs1
734 * arg[1] = ptr to rs2 or an immediate value (int32_t)
735 * arg[2] = ptr to rd
736 */
737 int32_t sparc_andcc32(struct cpu *cpu, int32_t rs1, int32_t rs2);
738 #ifdef MODE32
739 int32_t sparc_andcc32(struct cpu *cpu, int32_t rs1, int32_t rs2)
740 #else
741 int64_t sparc_andcc64(struct cpu *cpu, int64_t rs1, int64_t rs2)
742 #endif
743 {
744 int cc = 0, mask = SPARC_CCR_ICC_MASK;
745 MODE_int_t rd = rs1 & rs2;
746 if (rd == 0)
747 cc = SPARC_CCR_Z;
748 else if (rd < 0)
749 cc = SPARC_CCR_N;
750 /* Note: SPARC_CCR_C and SPARC_CCR_V are always zero. */
751 #ifndef MODE32
752 mask <<= SPARC_CCR_XCC_SHIFT;
753 cc <<= SPARC_CCR_XCC_SHIFT;
754 #endif
755 cpu->cd.sparc.ccr &= ~mask;
756 cpu->cd.sparc.ccr |= cc;
757 return rd;
758 }
759 X(andcc)
760 {
761 /* Like and, but updates the ccr, and does both 32-bit and
762 64-bit comparison at the same time. */
763 MODE_int_t rs1 = reg(ic->arg[0]), rs2 = reg(ic->arg[1]), rd;
764 rd = sparc_andcc32(cpu, rs1, rs2);
765 #ifndef MODE32
766 rd = sparc_andcc64(cpu, rs1, rs2);
767 #endif
768 reg(ic->arg[2]) = rd;
769 }
770 X(andcc_imm)
771 {
772 MODE_int_t rs1 = reg(ic->arg[0]), rs2 = (int32_t)ic->arg[1], rd;
773 rd = sparc_andcc32(cpu, rs1, rs2);
774 #ifndef MODE32
775 rd = sparc_andcc64(cpu, rs1, rs2);
776 #endif
777 reg(ic->arg[2]) = rd;
778 }
779
780
781 /*
782 * Subtract with ccr update:
783 *
784 * arg[0] = ptr to rs1
785 * arg[1] = ptr to rs2 or an immediate value (int32_t)
786 * arg[2] = ptr to rd
787 */
788 int32_t sparc_subcc32(struct cpu *cpu, int32_t rs1, int32_t rs2);
789 #ifdef MODE32
790 int32_t sparc_subcc32(struct cpu *cpu, int32_t rs1, int32_t rs2)
791 #else
792 int64_t sparc_subcc64(struct cpu *cpu, int64_t rs1, int64_t rs2)
793 #endif
794 {
795 int cc = 0, sign1 = 0, sign2 = 0, signd = 0, mask = SPARC_CCR_ICC_MASK;
796 MODE_int_t rd = rs1 - rs2;
797 if (rd == 0)
798 cc = SPARC_CCR_Z;
799 else if (rd < 0)
800 cc = SPARC_CCR_N, signd = 1;
801 if (rs1 < 0)
802 sign1 = 1;
803 if (rs2 < 0)
804 sign2 = 1;
805 if (sign1 != sign2 && sign1 != signd)
806 cc |= SPARC_CCR_V;
807 /* TODO: SPARC_CCR_C */
808 #ifndef MODE32
809 mask <<= SPARC_CCR_XCC_SHIFT;
810 cc <<= SPARC_CCR_XCC_SHIFT;
811 #endif
812 cpu->cd.sparc.ccr &= ~mask;
813 cpu->cd.sparc.ccr |= cc;
814 return rd;
815 }
816 X(subcc)
817 {
818 /* Like sub, but updates the ccr, and does both 32-bit and
819 64-bit comparison at the same time. */
820 MODE_int_t rs1 = reg(ic->arg[0]), rs2 = reg(ic->arg[1]), rd;
821 rd = sparc_subcc32(cpu, rs1, rs2);
822 #ifndef MODE32
823 rd = sparc_subcc64(cpu, rs1, rs2);
824 #endif
825 reg(ic->arg[2]) = rd;
826 }
827 X(subcc_imm)
828 {
829 MODE_int_t rs1 = reg(ic->arg[0]), rs2 = (int32_t)ic->arg[1], rd;
830 rd = sparc_subcc32(cpu, rs1, rs2);
831 #ifndef MODE32
832 rd = sparc_subcc64(cpu, rs1, rs2);
833 #endif
834 reg(ic->arg[2]) = rd;
835 }
836
837
838 #include "tmp_sparc_loadstore.c"
839
840
841 /*
842 * rd: Read special register
843 *
844 * arg[2] = ptr to rd
845 */
846 X(rd_psr)
847 {
848 reg(ic->arg[2]) = cpu->cd.sparc.psr;
849 }
850
851
852 /*
853 * rdpr: Read privileged register
854 *
855 * arg[2] = ptr to rd
856 */
857 X(rdpr_tba)
858 {
859 reg(ic->arg[2]) = cpu->cd.sparc.tba;
860 }
861 X(rdpr_ver)
862 {
863 reg(ic->arg[2]) = cpu->cd.sparc.ver;
864 }
865
866
867 /*
868 * wrpr: Write to privileged register
869 *
870 * arg[0] = ptr to rs1
871 * arg[1] = ptr to rs2 or an immediate value (int32_t)
872 */
873 X(wrpr_tick)
874 {
875 cpu->cd.sparc.tick = (uint32_t) (reg(ic->arg[0]) ^ reg(ic->arg[1]));
876 }
877 X(wrpr_tick_imm)
878 {
879 cpu->cd.sparc.tick = (uint32_t) (reg(ic->arg[0]) ^ (int32_t)ic->arg[1]);
880 }
881 X(wrpr_pil)
882 {
883 cpu->cd.sparc.pil = (reg(ic->arg[0]) ^ reg(ic->arg[1]))
884 & SPARC_PIL_MASK;
885 }
886 X(wrpr_pil_imm)
887 {
888 cpu->cd.sparc.pil = (reg(ic->arg[0]) ^ (int32_t)ic->arg[1])
889 & SPARC_PIL_MASK;
890 }
891 X(wrpr_pstate)
892 {
893 sparc_update_pstate(cpu, reg(ic->arg[0]) ^ reg(ic->arg[1]));
894 }
895 X(wrpr_pstate_imm)
896 {
897 sparc_update_pstate(cpu, reg(ic->arg[0]) ^ (int32_t)ic->arg[1]);
898 }
899
900
901 /*****************************************************************************/
902
903
904 X(end_of_page)
905 {
906 /* Update the PC: (offset 0, but on the next page) */
907 cpu->pc &= ~((SPARC_IC_ENTRIES_PER_PAGE-1) <<
908 SPARC_INSTR_ALIGNMENT_SHIFT);
909 cpu->pc += (SPARC_IC_ENTRIES_PER_PAGE <<
910 SPARC_INSTR_ALIGNMENT_SHIFT);
911
912 /* Find the new physical page and update the translation pointers: */
913 quick_pc_to_pointers(cpu);
914
915 /* end_of_page doesn't count as an executed instruction: */
916 cpu->n_translated_instrs --;
917 }
918
919
920 X(end_of_page2)
921 {
922 /* Synchronize PC on the _second_ instruction on the next page: */
923 int low_pc = ((size_t)ic - (size_t)cpu->cd.sparc.cur_ic_page)
924 / sizeof(struct sparc_instr_call);
925 cpu->pc &= ~((SPARC_IC_ENTRIES_PER_PAGE-1)
926 << SPARC_INSTR_ALIGNMENT_SHIFT);
927 cpu->pc += (low_pc << SPARC_INSTR_ALIGNMENT_SHIFT);
928
929 /* This doesn't count as an executed instruction. */
930 cpu->n_translated_instrs --;
931
932 quick_pc_to_pointers(cpu);
933
934 if (cpu->delay_slot == NOT_DELAYED)
935 return;
936
937 fatal("end_of_page2: fatal error, we're in a delay slot\n");
938 exit(1);
939 }
940
941
942 /*****************************************************************************/
943
944
945 /*
946 * sparc_instr_to_be_translated():
947 *
948 * Translate an instruction word into a sparc_instr_call. ic is filled in with
949 * valid data for the translated instruction, or a "nothing" instruction if
950 * there was a translation failure. The newly translated instruction is then
951 * executed.
952 */
953 X(to_be_translated)
954 {
955 MODE_uint_t addr;
956 int low_pc, in_crosspage_delayslot = 0;
957 uint32_t iword;
958 unsigned char *page;
959 unsigned char ib[4];
960 int main_opcode, op2, rd, rs1, rs2, btype, asi, cc, p, use_imm, x64 = 0;
961 int store, signedness, size;
962 int32_t tmpi32, siconst;
963 /* void (*samepage_function)(struct cpu *, struct sparc_instr_call *);*/
964
965 /* Figure out the (virtual) address of the instruction: */
966 low_pc = ((size_t)ic - (size_t)cpu->cd.sparc.cur_ic_page)
967 / sizeof(struct sparc_instr_call);
968
969 /* Special case for branch with delayslot on the next page: */
970 if (cpu->delay_slot == TO_BE_DELAYED && low_pc == 0) {
971 /* fatal("[ delay-slot translation across page "
972 "boundary ]\n"); */
973 in_crosspage_delayslot = 1;
974 }
975
976 addr = cpu->pc & ~((SPARC_IC_ENTRIES_PER_PAGE-1)
977 << SPARC_INSTR_ALIGNMENT_SHIFT);
978 addr += (low_pc << SPARC_INSTR_ALIGNMENT_SHIFT);
979 cpu->pc = addr;
980 addr &= ~((1 << SPARC_INSTR_ALIGNMENT_SHIFT) - 1);
981
982 /* Read the instruction word from memory: */
983 #ifdef MODE32
984 page = cpu->cd.sparc.host_load[addr >> 12];
985 #else
986 {
987 const uint32_t mask1 = (1 << DYNTRANS_L1N) - 1;
988 const uint32_t mask2 = (1 << DYNTRANS_L2N) - 1;
989 const uint32_t mask3 = (1 << DYNTRANS_L3N) - 1;
990 uint32_t x1 = (addr >> (64-DYNTRANS_L1N)) & mask1;
991 uint32_t x2 = (addr >> (64-DYNTRANS_L1N-DYNTRANS_L2N)) & mask2;
992 uint32_t x3 = (addr >> (64-DYNTRANS_L1N-DYNTRANS_L2N-
993 DYNTRANS_L3N)) & mask3;
994 struct DYNTRANS_L2_64_TABLE *l2 = cpu->cd.sparc.l1_64[x1];
995 struct DYNTRANS_L3_64_TABLE *l3 = l2->l3[x2];
996 page = l3->host_load[x3];
997 }
998 #endif
999
1000 if (page != NULL) {
1001 /* fatal("TRANSLATION HIT!\n"); */
1002 memcpy(ib, page + (addr & 0xffc), sizeof(ib));
1003 } else {
1004 /* fatal("TRANSLATION MISS!\n"); */
1005 if (!cpu->memory_rw(cpu, cpu->mem, addr, ib,
1006 sizeof(ib), MEM_READ, CACHE_INSTRUCTION)) {
1007 fatal("to_be_translated(): "
1008 "read failed: TODO\n");
1009 goto bad;
1010 }
1011 }
1012
1013 /* SPARC instruction words are always big-endian. Convert
1014 to host order: */
1015 iword = BE32_TO_HOST( *((uint32_t *)&ib[0]) );
1016
1017
1018 #define DYNTRANS_TO_BE_TRANSLATED_HEAD
1019 #include "cpu_dyntrans.c"
1020 #undef DYNTRANS_TO_BE_TRANSLATED_HEAD
1021
1022
1023 /*
1024 * Translate the instruction:
1025 */
1026
1027 main_opcode = iword >> 30;
1028 rd = (iword >> 25) & 31;
1029 btype = rd & (N_SPARC_BRANCH_TYPES - 1);
1030 rs1 = (iword >> 14) & 31;
1031 use_imm = (iword >> 13) & 1;
1032 asi = (iword >> 5) & 0xff;
1033 rs2 = iword & 31;
1034 siconst = (int16_t)((iword & 0x1fff) << 3) >> 3;
1035 op2 = (main_opcode == 0)? ((iword >> 22) & 7) : ((iword >> 19) & 0x3f);
1036 cc = (iword >> 20) & 3;
1037 p = (iword >> 19) & 1;
1038
1039 switch (main_opcode) {
1040
1041 case 0: switch (op2) {
1042
1043 case 1: /* branch (icc or xcc) */
1044 tmpi32 = (iword << 13);
1045 tmpi32 >>= 11;
1046 ic->arg[0] = (int32_t)tmpi32 + (addr & 0xffc);
1047 /* rd contains the annul bit concatenated with 4 bits
1048 of condition code. cc=0 for icc, 2 for xcc: */
1049 /* TODO: samepage */
1050 switch (rd + (cc << 5)) {
1051 case 0x01: ic->f = instr(be); break;
1052 case 0x03: ic->f = instr(bl); break;
1053 case 0x09: ic->f = instr(bne); break;
1054 case 0x0a: ic->f = instr(bg); break;
1055 case 0x0b: ic->f = instr(bge); break;
1056 case 0x19: ic->f = instr(bne_a); break;
1057 case 0x41: ic->f = instr(be_xcc); break;
1058 case 0x43: ic->f = instr(bl_xcc); break;
1059 case 0x4a: ic->f = instr(bg_xcc); break;
1060 case 0x4b: ic->f = instr(bge_xcc); break;
1061 default:fatal("Unimplemented branch, 0x%x\n",
1062 rd + (cc<<5));
1063 goto bad;
1064 }
1065 break;
1066
1067 case 2: /* branch (32-bit integer comparison) */
1068 tmpi32 = (iword << 10);
1069 tmpi32 >>= 8;
1070 ic->arg[0] = (int32_t)tmpi32 + (addr & 0xffc);
1071 /* rd contains the annul bit concatenated with 4 bits
1072 of condition code: */
1073 /* TODO: samepage */
1074 switch (rd) {
1075 case 0x01: ic->f = instr(be); break;
1076 case 0x03: ic->f = instr(bl); break;
1077 case 0x08: ic->f = instr(ba); break;
1078 case 0x0b: ic->f = instr(bge); break;
1079 default:fatal("Unimplemented branch rd=%i\n", rd);
1080 goto bad;
1081 }
1082 break;
1083
1084 case 3: /* branch on register, 64-bit integer comparison */
1085 tmpi32 = ((iword & 0x300000) >> 6) | (iword & 0x3fff);
1086 tmpi32 <<= 16;
1087 tmpi32 >>= 14;
1088 ic->arg[0] = (int32_t)tmpi32 + (addr & 0xffc);
1089 ic->arg[1] = (size_t)&cpu->cd.sparc.r[rs1];
1090 /* TODO: samepage */
1091 switch (btype) {
1092 case 0x05: ic->f = instr(brnz); break;
1093 default:fatal("Unimplemented branch 0x%x\n", rd);
1094 goto bad;
1095 }
1096 break;
1097
1098 case 4: /* sethi */
1099 ic->arg[0] = (size_t)&cpu->cd.sparc.r[rd];
1100 ic->arg[1] = (iword & 0x3fffff) << 10;
1101 ic->f = instr(set);
1102 if (rd == SPARC_ZEROREG)
1103 ic->f = instr(nop);
1104 break;
1105
1106 default:fatal("TODO: unimplemented op2=%i for main "
1107 "opcode %i\n", op2, main_opcode);
1108 goto bad;
1109 }
1110 break;
1111
1112 case 1: /* call and link */
1113 tmpi32 = (iword << 2);
1114 ic->arg[0] = (int32_t)tmpi32;
1115 ic->arg[1] = addr & 0xffc;
1116 if (cpu->machine->show_trace_tree)
1117 ic->f = instr(call_trace);
1118 else
1119 ic->f = instr(call);
1120 /* TODO: samepage */
1121 break;
1122
1123 case 2: switch (op2) {
1124
1125 case 0: /* add */
1126 case 1: /* and */
1127 case 2: /* or */
1128 case 3: /* xor */
1129 case 4: /* sub */
1130 case 14:/* udiv */
1131 case 16:/* addcc */
1132 case 17:/* andcc */
1133 case 20:/* subcc (cmp) */
1134 case 37:/* sll */
1135 case 38:/* srl */
1136 case 39:/* sra */
1137 case 60:/* save */
1138 ic->arg[0] = (size_t)&cpu->cd.sparc.r[rs1];
1139 ic->f = NULL;
1140 if (use_imm) {
1141 ic->arg[1] = siconst;
1142 switch (op2) {
1143 case 0: ic->f = instr(add_imm); break;
1144 case 1: ic->f = instr(and_imm); break;
1145 case 2: ic->f = instr(or_imm); break;
1146 case 3: ic->f = instr(xor_imm); break;
1147 case 4: ic->f = instr(sub_imm); break;
1148 case 14:ic->f = instr(udiv_imm); break;
1149 case 16:ic->f = instr(addcc_imm); break;
1150 case 17:ic->f = instr(andcc_imm); break;
1151 case 20:ic->f = instr(subcc_imm); break;
1152 case 37:if (siconst & 0x1000) {
1153 ic->f = instr(sllx_imm);
1154 ic->arg[1] &= 63;
1155 x64 = 1;
1156 } else {
1157 ic->f = instr(sll_imm);
1158 ic->arg[1] &= 31;
1159 }
1160 break;
1161 case 38:if (siconst & 0x1000) {
1162 ic->f = instr(srlx_imm);
1163 ic->arg[1] &= 63;
1164 x64 = 1;
1165 } else {
1166 ic->f = instr(srl_imm);
1167 ic->arg[1] &= 31;
1168 }
1169 break;
1170 case 39:if (siconst & 0x1000) {
1171 ic->f = instr(srax_imm);
1172 ic->arg[1] &= 63;
1173 x64 = 1;
1174 } else {
1175 ic->f = instr(sra_imm);
1176 ic->arg[1] &= 31;
1177 }
1178 break;
1179 case 60:switch (cpu->cd.sparc.cpu_type.v) {
1180 case 9: ic->f = instr(save_v9_imm);
1181 break;
1182 default:fatal("only for v9 so far\n");
1183 goto bad;
1184 }
1185 }
1186 } else {
1187 ic->arg[1] = (size_t)&cpu->cd.sparc.r[rs2];
1188 switch (op2) {
1189 case 0: ic->f = instr(add); break;
1190 case 1: ic->f = instr(and); break;
1191 case 2: ic->f = instr(or); break;
1192 case 3: ic->f = instr(xor); break;
1193 case 4: ic->f = instr(sub); break;
1194 case 14:ic->f = instr(udiv); break;
1195 case 16:ic->f = instr(addcc); break;
1196 case 17:ic->f = instr(andcc); break;
1197 case 20:ic->f = instr(subcc); break;
1198 case 37:if (siconst & 0x1000) {
1199 ic->f = instr(sllx);
1200 x64 = 1;
1201 } else
1202 ic->f = instr(sll);
1203 break;
1204 case 38:if (siconst & 0x1000) {
1205 ic->f = instr(srlx);
1206 x64 = 1;
1207 } else
1208 ic->f = instr(srl);
1209 break;
1210 case 39:if (siconst & 0x1000) {
1211 ic->f = instr(srax);
1212 x64 = 1;
1213 } else
1214 ic->f = instr(sra);
1215 break;
1216 }
1217 }
1218 if (ic->f == NULL) {
1219 fatal("TODO: Unimplemented instruction "
1220 "(possibly missed use_imm impl.)\n");
1221 goto bad;
1222 }
1223 ic->arg[2] = (size_t)&cpu->cd.sparc.r[rd];
1224 if (rd == SPARC_ZEROREG) {
1225 /*
1226 * Some opcodes should write to the scratch
1227 * register instead of becoming NOPs, when
1228 * rd is the zero register.
1229 *
1230 * Any opcode which updates the condition
1231 * codes, or anything which changes register
1232 * windows.
1233 */
1234 switch (op2) {
1235 case 16:/* addcc */
1236 case 17:/* andcc */
1237 case 20:/* subcc */
1238 case 60:/* save */
1239 ic->arg[2] = (size_t)
1240 &cpu->cd.sparc.scratch;
1241 break;
1242 default:ic->f = instr(nop);
1243 }
1244 }
1245 break;
1246
1247 case 41:/* rd %psr,%gpr on pre-sparcv9 */
1248 if (cpu->is_32bit) {
1249 ic->f = instr(rd_psr);
1250 ic->arg[2] = (size_t)&cpu->cd.sparc.r[rd];
1251 if (rd == SPARC_ZEROREG)
1252 ic->f = instr(nop);
1253 } else {
1254 fatal("opcode 2,41 not yet implemented"
1255 " for 64-bit cpus\n");
1256 goto bad;
1257 }
1258 break;
1259
1260 case 42:/* rdpr on sparcv9 */
1261 if (cpu->is_32bit) {
1262 fatal("opcode 2,42 not yet implemented"
1263 " for 32-bit cpus\n");
1264 goto bad;
1265 }
1266 ic->arg[2] = (size_t)&cpu->cd.sparc.r[rd];
1267 if (rd == SPARC_ZEROREG)
1268 ic->f = instr(nop);
1269 switch (rs1) {
1270 case 5: ic->f = instr(rdpr_tba); break;
1271 case 31: ic->f = instr(rdpr_ver); break;
1272 default:fatal("Unimplemented rs1=%i\n", rs1);
1273 goto bad;
1274 }
1275 break;
1276
1277 case 48:/* wr (Note: works as xor) */
1278 ic->arg[0] = (size_t)&cpu->cd.sparc.r[rs1];
1279 if (use_imm) {
1280 ic->arg[1] = siconst;
1281 ic->f = instr(xor_imm);
1282 } else {
1283 ic->arg[1] = (size_t)&cpu->cd.sparc.r[rs2];
1284 ic->f = instr(xor);
1285 }
1286 ic->arg[2] = (size_t) NULL;
1287 switch (rd) {
1288 case 0: ic->arg[2] = (size_t)&cpu->cd.sparc.y;
1289 break;
1290 case 6: ic->arg[2] = (size_t)&cpu->cd.sparc.fprs;
1291 break;
1292 case 0x17:
1293 ic->arg[2] = (size_t)&cpu->cd.sparc.tick_cmpr;
1294 break;
1295 }
1296 if (ic->arg[2] == (size_t)NULL) {
1297 fatal("TODO: Unimplemented wr instruction, "
1298 "rd = 0x%02x\n", rd);
1299 goto bad;
1300 }
1301 break;
1302
1303 case 50:/* wrpr (Note: works as xor) */
1304 ic->arg[0] = (size_t)&cpu->cd.sparc.r[rs1];
1305 ic->f = NULL;
1306 if (use_imm) {
1307 ic->arg[1] = siconst;
1308 switch (rd) {
1309 case 4: ic->f = instr(wrpr_tick_imm); break;
1310 case 6: ic->f = instr(wrpr_pstate_imm); break;
1311 case 8: ic->f = instr(wrpr_pil_imm); break;
1312 }
1313 } else {
1314 ic->arg[1] = (size_t)&cpu->cd.sparc.r[rs2];
1315 switch (rd) {
1316 case 4: ic->f = instr(wrpr_tick); break;
1317 case 6: ic->f = instr(wrpr_pstate); break;
1318 case 8: ic->f = instr(wrpr_pil); break;
1319 }
1320 }
1321 if (ic->f == NULL) {
1322 fatal("TODO: Unimplemented wrpr instruction,"
1323 " rd = 0x%02x\n", rd);
1324 goto bad;
1325 }
1326 break;
1327
1328 case 56:/* jump and link */
1329 ic->arg[0] = (size_t)&cpu->cd.sparc.r[rs1];
1330 ic->arg[2] = (size_t)&cpu->cd.sparc.r[rd];
1331 if (rd == SPARC_ZEROREG)
1332 ic->arg[2] = (size_t)&cpu->cd.sparc.scratch;
1333
1334 if (use_imm) {
1335 ic->arg[1] = siconst;
1336 if (rd == SPARC_ZEROREG)
1337 ic->f = instr(jmpl_imm_no_rd);
1338 else
1339 ic->f = instr(jmpl_imm);
1340 } else {
1341 ic->arg[1] = (size_t)&cpu->cd.sparc.r[rs2];
1342 if (rd == SPARC_ZEROREG)
1343 ic->f = instr(jmpl_reg_no_rd);
1344 else
1345 ic->f = instr(jmpl_reg);
1346 }
1347
1348 /* special trace case: */
1349 if (cpu->machine->show_trace_tree) {
1350 if (iword == 0x81c3e008)
1351 ic->f = instr(retl_trace);
1352 else {
1353 if (use_imm)
1354 ic->f = instr(jmpl_imm_trace);
1355 else
1356 ic->f = instr(jmpl_reg_trace);
1357 }
1358 }
1359 break;
1360
1361 default:fatal("TODO: unimplemented op2=%i for main "
1362 "opcode %i\n", op2, main_opcode);
1363 goto bad;
1364 }
1365 break;
1366
1367 case 3: switch (op2) {
1368
1369 case 0:/* lduw */
1370 case 1:/* ldub */
1371 case 2:/* lduh */
1372 case 4:/* st(w) */
1373 case 5:/* stb */
1374 case 6:/* sth */
1375 case 8:/* ldsw */
1376 case 9:/* ldsb */
1377 case 10:/* ldsh */
1378 case 11:/* ldx */
1379 case 14:/* stx */
1380 store = 1; signedness = 0; size = 3;
1381 switch (op2) {
1382 case 0: /* lduw */ store=0; size=2; break;
1383 case 1: /* ldub */ store=0; size=0; break;
1384 case 2: /* lduh */ store=0; size=1; break;
1385 case 4: /* st */ size = 2; break;
1386 case 5: /* stb */ size = 0; break;
1387 case 6: /* sth */ size = 1; break;
1388 case 8: /* ldsw */ store=0; size=2; signedness=1;
1389 break;
1390 case 9: /* ldsb */ store=0; size=0; signedness=1;
1391 break;
1392 case 10: /* ldsh */ store=0; size=1; signedness=1;
1393 break;
1394 case 11: /* ldx */ store=0; break;
1395 case 14: /* stx */ break;
1396 }
1397 ic->f =
1398 #ifdef MODE32
1399 sparc32_loadstore
1400 #else
1401 sparc_loadstore
1402 #endif
1403 [ use_imm*16 + store*8 + size*2 + signedness ];
1404
1405 ic->arg[0] = (size_t)&cpu->cd.sparc.r[rd];
1406 ic->arg[1] = (size_t)&cpu->cd.sparc.r[rs1];
1407 if (use_imm)
1408 ic->arg[2] = siconst;
1409 else
1410 ic->arg[2] = (size_t)&cpu->cd.sparc.r[rs2];
1411
1412 if (!store && rd == SPARC_ZEROREG)
1413 ic->arg[0] = (size_t)&cpu->cd.sparc.scratch;
1414
1415 break;
1416
1417 default:fatal("TODO: unimplemented op2=%i for main "
1418 "opcode %i\n", op2, main_opcode);
1419 goto bad;
1420 }
1421 break;
1422
1423 }
1424
1425
1426 if (x64 && cpu->is_32bit) {
1427 fatal("TODO: 64-bit instr on 32-bit cpu\n");
1428 goto bad;
1429 }
1430
1431
1432 #define DYNTRANS_TO_BE_TRANSLATED_TAIL
1433 #include "cpu_dyntrans.c"
1434 #undef DYNTRANS_TO_BE_TRANSLATED_TAIL
1435 }
1436

  ViewVC Help
Powered by ViewVC 1.1.26