/[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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 24 - (hide annotations)
Mon Oct 8 16:19:56 2007 UTC (16 years, 6 months ago) by dpavlin
File MIME type: text/plain
File size: 23061 byte(s)
++ trunk/HISTORY	(local)
$Id: HISTORY,v 1.1256 2006/06/23 20:43:44 debug Exp $
20060219	Various minor updates. Removing the old MIPS16 skeleton code,
		because it will need to be rewritten for dyntrans anyway.
20060220-22	Removing the non-working dyntrans backend support.
		Continuing on the 64-bit dyntrans virtual memory generalization.
20060223	More work on the 64-bit vm generalization.
20060225	Beginning on MIPS dyntrans load/store instructions.
		Minor PPC updates (64-bit load/store, etc).
		Fixes for the variable-instruction-length framework, some
		minor AVR updates (a simple Hello World program works!).
		Beginning on a skeleton for automatically generating documen-
		tation (for devices etc.).
20060226	PPC updates (adding some more 64-bit instructions, etc).
		AVR updates (more instructions).
		FINALLY found and fixed the zs bug, making NetBSD/macppc
		accept the serial console.
20060301	Adding more AVR instructions.
20060304	Continuing on AVR-related stuff. Beginning on a framework for
		cycle-accurate device emulation. Adding an experimental "PAL
		TV" device (just a dummy so far).
20060305	Adding more AVR instructions.
		Adding a dummy epcom serial controller (for TS7200 emulation).
20060310	Removing the emul() command from configuration files, so only
		net() and machine() are supported.
		Minor progress on the MIPS dyntrans rewrite.
20060311	Continuing on the MIPS dyntrans rewrite (adding more
		instructions, etc).
20060315	Adding more instructions (sllv, srav, srlv, bgtz[l], blez[l],
		beql, bnel, slti[u], various loads and stores).
20060316	Removing the ALWAYS_SIGNEXTEND_32 option, since it was rarely
		used.
		Adding more MIPS dyntrans instructions, and fixing bugs.
20060318	Implementing fast loads/stores for MIPS dyntrans (big/little
		endian, 32-bit and 64-bit modes).
20060320	Making MIPS dyntrans the default configure option; use
		"--enable-oldmips" to use the old bintrans system.
		Adding MIPS dyntrans dmult[u]; minor updates.
20060322	Continuing... adding some more instructions.
		Adding a simple skeleton for demangling C++ "_ZN" symbols.
20060323	Moving src/debugger.c into a new directory (src/debugger/).
20060324	Fixing the hack used to load PPC ELFs (useful for relocated
		Linux/ppc kernels), and adding a dummy G3 machine mode.
20060325-26	Beginning to experiment with GDB remote serial protocol
		connections; adding a -G command line option for selecting
		which TCP port to listen to.
20060330	Beginning a major cleanup to replace things like "0x%016llx"
		with more correct "0x%016"PRIx64, etc.
		Continuing on the GDB remote serial protocol support.
20060331	More cleanup, and some minor GDB remote progress.
20060402	Adding a hack to the configure script, to allow compilation
		on systems that lack PRIx64 etc.
20060406	Removing the temporary FreeBSD/arm hack in dev_ns16550.c and
		replacing it with a better fix from Olivier Houchard.
20060407	A remote debugger (gdb or ddd) can now start and stop the
		emulator using the GDB remote serial protocol, and registers
		and memory can be read. MIPS only for now.
20060408	More GDB progress: single-stepping also works, and also adding
		support for ARM, PowerPC, and Alpha targets.
		Continuing on the delay-slot-across-page-boundary issue.
20060412	Minor update: beginning to add support for the SPARC target
		to the remote GDB functionality.
20060414	Various MIPS updates: adding more instructions for dyntrans
		(eret, add), and making some exceptions work. Fixing a bug
		in dmult[u].
		Implementing the first SPARC instructions (sethi, or).
20060415	Adding "magic trap" instructions so that PROM calls can be
		software emulated in MIPS dyntrans.
		Adding more MIPS dyntrans instructions (ddiv, dadd) and
		fixing another bug in dmult.
20060416	More MIPS dyntrans progress: adding [d]addi, movn, movz, dsllv,
		rfi, an ugly hack for supporting R2000/R3000 style faked caches,
		preliminary interrupt support, and various other updates and
		bugfixes.
20060417	Adding more SPARC instructions (add, sub, sll[x], sra[x],
		srl[x]), and useful SPARC header definitions.
		Adding the first (trivial) x86/AMD64 dyntrans instructions (nop,
		cli/sti, stc/clc, std/cld, simple mov, inc ax). Various other
		x86 updates related to variable instruction length stuff.
		Adding unaligned loads/stores to the MIPS dyntrans mode (but
		still using the pre-dyntrans (slow) imlementation).
20060419	Fixing a MIPS dyntrans exception-in-delay-slot bug.
		Removing the old "show opcode statistics" functionality, since
		it wasn't really useful and isn't implemented for dyntrans.
		Single-stepping (or running with instruction trace) now looks
		ok with dyntrans with delay-slot architectures.
20060420	Minor hacks (removing the -B command line option when compiled
		for non-bintrans, and some other very minor updates).
		Adding (slow) MIPS dyntrans load-linked/store-conditional.
20060422	Applying fixes for bugs discovered by Nils Weller's nwcc
		(static DEC memmap => now per machine, and adding an extern
		keyword in cpu_arm_instr.c).
		Finally found one of the MIPS dyntrans bugs that I've been
		looking for (copy/paste spelling error BIG vs LITTLE endian in
		cpu_mips_instr_loadstore.c for 16-bit fast stores).
		FINALLY found the major MIPS dyntrans bug: slti vs sltiu
		signed/unsigned code in cpu_mips_instr.c. :-)
		Adding more MIPS dyntrans instructions (lwc1, swc1, bgezal[l],
		ctc1, tlt[u], tge[u], tne, beginning on rdhwr).
		NetBSD/hpcmips can now reach userland when using dyntrans :-)
		Adding some more x86 dyntrans instructions.
		Finally removed the old Alpha-specific virtual memory code,
		and replaced it with the generic 64-bit version.
		Beginning to add disassembly support for SPECIAL3 MIPS opcodes.
20060423	Continuing on the delay-slot-across-page-boundary issue;
		adding an end_of_page2 ic slot (like I had planned before, but
		had removed for some reason).
		Adding a quick-and-dirty fallback to legacy coprocessor 1
		code (i.e. skipping dyntrans implementation for now).
		NetBSD/hpcmips and NetBSD/pmax (when running on an emulated
		R4400) can now be installed and run. :-)  (Many bugs left
		to fix, though.)
		Adding more MIPS dyntrans instructions: madd[u], msub[u].
		Cleaning up the SPECIAL2 vs R5900/TX79/C790 "MMI" opcode
		maps somewhat (disassembly and dyntrans instruction decoding).
20060424	Adding an isa_revision field to mips_cpu_types.h, and making
		sure that SPECIAL3 opcodes cause Reserved Instruction
		exceptions on MIPS32/64 revisions lower than 2.
		Adding the SPARC 'ba', 'call', 'jmpl/retl', 'and', and 'xor'
		instructions.
20060425	Removing the -m command line option ("run at most x 
		instructions") and -T ("single_step_on_bad_addr"), because
		they never worked correctly with dyntrans anyway.
		Freshening up the man page.
20060428	Adding more MIPS dyntrans instructions: bltzal[l], idle.
		Enabling MIPS dyntrans compare interrupts.
20060429	FINALLY found the weird dyntrans bug, causing NetBSD etc. to
		behave strangely: some floating point code (conditional
		coprocessor branches) could not be reused from the old
		non-dyntrans code. The "quick-and-dirty fallback" only appeared
		to work. Fixing by implementing bc1* for MIPS dyntrans.
		More MIPS instructions: [d]sub, sdc1, ldc1, dmtc1, dmfc1, cfc0.
		Freshening up MIPS floating point disassembly appearance.
20060430	Continuing on C790/R5900/TX79 disassembly; implementing 128-bit
		"por" and "pextlw".
20060504	Disabling -u (userland emulation) unless compiled as unstable
		development version.
		Beginning on freshening up the testmachine include files,
		to make it easier to reuse those files (placing them in
		src/include/testmachine/), and beginning on a set of "demos"
		or "tutorials" for the testmachine functionality.
		Minor updates to the MIPS GDB remote protocol stub.
		Refreshing doc/experiments.html and gdb_remote.html.
		Enabling Alpha emulation in the stable release configuration,
		even though no guest OSes for Alpha can run yet.
20060505	Adding a generic 'settings' object, which will contain
		references to settable variables (which will later be possible
		to access using the debugger).
20060506	Updating dev_disk and corresponding demo/documentation (and
		switching from SCSI to IDE disk types, so it actually works
		with current test machines :-).
20060510	Adding a -D_LARGEFILE_SOURCE hack for 64-bit Linux hosts,
		so that fseeko() doesn't give a warning.
		Updating the section about how dyntrans works (the "runnable
		IR") in doc/intro.html.
		Instruction updates (some x64=1 checks, some more R5900
		dyntrans stuff: better mul/mult separation from MIPS32/64,
		adding ei and di).
		Updating MIPS cpuregs.h to a newer one (from NetBSD).
		Adding more MIPS dyntrans instructions: deret, ehb.
20060514	Adding disassembly and beginning implementation of SPARC wr
		and wrpr instructions.
20060515	Adding a SUN SPARC machine mode, with dummy SS20 and Ultra1
		machines. Adding the 32-bit "rd psr" instruction.
20060517	Disassembly support for the general SPARC rd instruction.
		Partial implementation of the cmp (subcc) instruction.
		Some other minor updates (making sure that R5900 processors
		start up with the EIE bit enabled, otherwise Linux/playstation2
		receives no interrupts).
20060519	Minor MIPS updates/cleanups.
20060521	Moving the MeshCube machine into evbmips; this seems to work
		reasonably well with a snapshot of a NetBSD MeshCube kernel.
		Cleanup/fix of MIPS config0 register initialization.
20060529	Minor MIPS fixes, including a sign-extension fix to the
		unaligned load/store code, which makes NetBSD/pmax on R3000
		work better with dyntrans. (Ultrix and Linux/DECstation still
		don't work, though.)
20060530	Minor updates to the Alpha machine mode: adding an AlphaBook
		mode, an LCA bus (forwarding accesses to an ISA bus), etc.
20060531	Applying a bugfix for the MIPS dyntrans sc[d] instruction from
		Ondrej Palkovsky. (Many thanks.)
20060601	Minifix to allow ARM immediate msr instruction to not give
		an error for some valid values.
		More Alpha updates.
20060602	Some minor Alpha updates.
20060603	Adding the Alpha cmpbge instruction. NetBSD/alpha prints its
		first boot messages :-) on an emulated Alphabook 1.
20060612	Minor updates; adding a dev_ether.h include file for the
		testmachine ether device. Continuing the hunt for the dyntrans
		bug which makes Linux and Ultrix on DECstation behave
		strangely... FINALLY found it! It seems to be related to
		invalidation of the translation cache, on tlbw{r,i}. There
		also seems to be some remaining interrupt-related problems.
20060614	Correcting the implementation of ldc1/sdc1 for MIPS dyntrans
		(so that it uses 16 32-bit registers if the FR bit in the
		status register is not set).
20060616	REMOVING BINTRANS COMPLETELY!
		Removing the old MIPS interpretation mode.
		Removing the MFHILO_DELAY and instruction delay stuff, because
		they wouldn't work with dyntrans anyway.
20060617	Some documentation updates (adding "NetBSD-archive" to some
		URLs, and new Debian/DECstation installation screenshots).
		Removing the "tracenull" and "enable-caches" configure options.
		Improving MIPS dyntrans performance somewhat (only invalidate
		translations if necessary, on writes to the entryhi register,
		instead of doing it for all cop0 writes).
20060618	More cleanup after the removal of the old MIPS emulation.
		Trying to fix the MIPS dyntrans performance bugs/bottlenecks;
		only semi-successful so far (for R3000).
20060620	Minor update to allow clean compilation again on Tru64/Alpha.
20060622	MIPS cleanup and fixes (removing the pc_last stuff, which
		doesn't make sense with dyntrans anyway, and fixing a cross-
		page-delay-slot-with-exception case in end_of_page).
		Removing the old max_random_cycles_per_chunk stuff, and the
		concept of cycles vs instructions for MIPS emulation.
		FINALLY found and fixed the bug which caused NetBSD/pmax
		clocks to behave strangely (it was a load to the zero register,
		which was treated as a NOP; now it is treated as a load to a
		dummy scratch register).
20060623	Increasing the dyntrans chunk size back to
		N_SAFE_DYNTRANS_LIMIT, instead of N_SAFE_DYNTRANS_LIMIT/2.
		Preparing for a quick release, even though there are known
		bugs, and performance for non-R3000 MIPS emulation is very
		poor. :-/
		Reverting to half the dyntrans chunk size again, because
		NetBSD/cats seemed less stable with full size chunks. :(
		NetBSD/sgimips 3.0 can now run :-)  (With release 0.3.8, only
		NetBSD/sgimips 2.1 worked, not 3.0.)

==============  RELEASE 0.4.0  ==============


1 dpavlin 14 /*
2 dpavlin 22 * Copyright (C) 2005-2006 Anders Gavare. All rights reserved.
3 dpavlin 14 *
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 dpavlin 24 * $Id: cpu_sparc_instr.c,v 1.18 2006/05/17 20:27:31 debug Exp $
29 dpavlin 14 *
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     * nop: Do nothing.
41     */
42     X(nop)
43     {
44     }
45    
46    
47     /*****************************************************************************/
48    
49    
50 dpavlin 24 /*
51     * call
52     *
53     * arg[0] = int32_t displacement compared to the current instruction
54     * arg[1] = int32_t displacement of current instruction compared to
55     * start of the page
56     */
57     X(call)
58     {
59     MODE_uint_t old_pc = cpu->pc;
60     old_pc &= ~((SPARC_IC_ENTRIES_PER_PAGE - 1)
61     << SPARC_INSTR_ALIGNMENT_SHIFT);
62     old_pc += (int32_t)ic->arg[1];
63     cpu->cd.sparc.r[SPARC_REG_O7] = old_pc;
64     cpu->delay_slot = TO_BE_DELAYED;
65     ic[1].f(cpu, ic+1);
66     cpu->n_translated_instrs ++;
67     if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
68     /* Note: Must be non-delayed when jumping to the new pc: */
69     cpu->delay_slot = NOT_DELAYED;
70     cpu->pc = old_pc + (int32_t)ic->arg[0];
71     quick_pc_to_pointers(cpu);
72     } else
73     cpu->delay_slot = NOT_DELAYED;
74     }
75     X(call_trace)
76     {
77     MODE_uint_t old_pc = cpu->pc;
78     old_pc &= ~((SPARC_IC_ENTRIES_PER_PAGE - 1)
79     << SPARC_INSTR_ALIGNMENT_SHIFT);
80     old_pc += (int32_t)ic->arg[1];
81     cpu->cd.sparc.r[SPARC_REG_O7] = old_pc;
82     cpu->delay_slot = TO_BE_DELAYED;
83     ic[1].f(cpu, ic+1);
84     cpu->n_translated_instrs ++;
85     if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
86     /* Note: Must be non-delayed when jumping to the new pc: */
87     cpu->delay_slot = NOT_DELAYED;
88     cpu->pc = old_pc + (int32_t)ic->arg[0];
89     cpu_functioncall_trace(cpu, cpu->pc);
90     quick_pc_to_pointers(cpu);
91     } else
92     cpu->delay_slot = NOT_DELAYED;
93     }
94    
95    
96     /*
97     * ba
98     *
99     * arg[0] = int32_t displacement compared to the start of the current page
100     */
101     X(ba)
102     {
103     MODE_uint_t old_pc = cpu->pc;
104     cpu->delay_slot = TO_BE_DELAYED;
105     ic[1].f(cpu, ic+1);
106     cpu->n_translated_instrs ++;
107     if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
108     /* Note: Must be non-delayed when jumping to the new pc: */
109     cpu->delay_slot = NOT_DELAYED;
110     old_pc &= ~((SPARC_IC_ENTRIES_PER_PAGE - 1)
111     << SPARC_INSTR_ALIGNMENT_SHIFT);
112     cpu->pc = old_pc + (int32_t)ic->arg[0];
113     quick_pc_to_pointers(cpu);
114     } else
115     cpu->delay_slot = NOT_DELAYED;
116     }
117    
118    
119     /*
120     * Jump and link
121     *
122     * arg[0] = ptr to rs1
123     * arg[1] = ptr to rs2 or an immediate value (int32_t)
124     * arg[2] = ptr to rd
125     */
126     X(jmpl_imm)
127     {
128     int low_pc = ((size_t)ic - (size_t)cpu->cd.sparc.cur_ic_page)
129     / sizeof(struct sparc_instr_call);
130     cpu->pc &= ~((SPARC_IC_ENTRIES_PER_PAGE-1)
131     << SPARC_INSTR_ALIGNMENT_SHIFT);
132     cpu->pc += (low_pc << SPARC_INSTR_ALIGNMENT_SHIFT);
133     reg(ic->arg[2]) = cpu->pc;
134    
135     cpu->delay_slot = TO_BE_DELAYED;
136     ic[1].f(cpu, ic+1);
137     cpu->n_translated_instrs ++;
138    
139     if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
140     /* Note: Must be non-delayed when jumping to the new pc: */
141     cpu->delay_slot = NOT_DELAYED;
142     cpu->pc = reg(ic->arg[0]) + (int32_t)ic->arg[1];
143     quick_pc_to_pointers(cpu);
144     } else
145     cpu->delay_slot = NOT_DELAYED;
146     }
147     X(jmpl_imm_no_rd)
148     {
149     int low_pc = ((size_t)ic - (size_t)cpu->cd.sparc.cur_ic_page)
150     / sizeof(struct sparc_instr_call);
151     cpu->pc &= ~((SPARC_IC_ENTRIES_PER_PAGE-1)
152     << SPARC_INSTR_ALIGNMENT_SHIFT);
153     cpu->pc += (low_pc << SPARC_INSTR_ALIGNMENT_SHIFT);
154    
155     cpu->delay_slot = TO_BE_DELAYED;
156     ic[1].f(cpu, ic+1);
157     cpu->n_translated_instrs ++;
158    
159     if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
160     /* Note: Must be non-delayed when jumping to the new pc: */
161     cpu->delay_slot = NOT_DELAYED;
162     cpu->pc = reg(ic->arg[0]) + (int32_t)ic->arg[1];
163     quick_pc_to_pointers(cpu);
164     } else
165     cpu->delay_slot = NOT_DELAYED;
166     }
167     X(jmpl_reg)
168     {
169     int low_pc = ((size_t)ic - (size_t)cpu->cd.sparc.cur_ic_page)
170     / sizeof(struct sparc_instr_call);
171     cpu->pc &= ~((SPARC_IC_ENTRIES_PER_PAGE-1)
172     << SPARC_INSTR_ALIGNMENT_SHIFT);
173     cpu->pc += (low_pc << SPARC_INSTR_ALIGNMENT_SHIFT);
174     reg(ic->arg[2]) = cpu->pc;
175    
176     cpu->delay_slot = TO_BE_DELAYED;
177     ic[1].f(cpu, ic+1);
178     cpu->n_translated_instrs ++;
179    
180     if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
181     /* Note: Must be non-delayed when jumping to the new pc: */
182     cpu->delay_slot = NOT_DELAYED;
183     cpu->pc = reg(ic->arg[0]) + reg(ic->arg[1]);
184     quick_pc_to_pointers(cpu);
185     } else
186     cpu->delay_slot = NOT_DELAYED;
187     }
188     X(jmpl_reg_no_rd)
189     {
190     int low_pc = ((size_t)ic - (size_t)cpu->cd.sparc.cur_ic_page)
191     / sizeof(struct sparc_instr_call);
192     cpu->pc &= ~((SPARC_IC_ENTRIES_PER_PAGE-1)
193     << SPARC_INSTR_ALIGNMENT_SHIFT);
194     cpu->pc += (low_pc << SPARC_INSTR_ALIGNMENT_SHIFT);
195    
196     cpu->delay_slot = TO_BE_DELAYED;
197     ic[1].f(cpu, ic+1);
198     cpu->n_translated_instrs ++;
199    
200     if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
201     /* Note: Must be non-delayed when jumping to the new pc: */
202     cpu->delay_slot = NOT_DELAYED;
203     cpu->pc = reg(ic->arg[0]) + reg(ic->arg[1]);
204     quick_pc_to_pointers(cpu);
205     } else
206     cpu->delay_slot = NOT_DELAYED;
207     }
208    
209    
210     X(jmpl_imm_trace)
211     {
212     int low_pc = ((size_t)ic - (size_t)cpu->cd.sparc.cur_ic_page)
213     / sizeof(struct sparc_instr_call);
214     cpu->pc &= ~((SPARC_IC_ENTRIES_PER_PAGE-1)
215     << SPARC_INSTR_ALIGNMENT_SHIFT);
216     cpu->pc += (low_pc << SPARC_INSTR_ALIGNMENT_SHIFT);
217     reg(ic->arg[2]) = cpu->pc;
218    
219     cpu->delay_slot = TO_BE_DELAYED;
220     ic[1].f(cpu, ic+1);
221     cpu->n_translated_instrs ++;
222    
223     if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
224     /* Note: Must be non-delayed when jumping to the new pc: */
225     cpu->delay_slot = NOT_DELAYED;
226     cpu->pc = reg(ic->arg[0]) + (int32_t)ic->arg[1];
227     cpu_functioncall_trace(cpu, cpu->pc);
228     quick_pc_to_pointers(cpu);
229     } else
230     cpu->delay_slot = NOT_DELAYED;
231     }
232     X(jmpl_reg_trace)
233     {
234     int low_pc = ((size_t)ic - (size_t)cpu->cd.sparc.cur_ic_page)
235     / sizeof(struct sparc_instr_call);
236     cpu->pc &= ~((SPARC_IC_ENTRIES_PER_PAGE-1)
237     << SPARC_INSTR_ALIGNMENT_SHIFT);
238     cpu->pc += (low_pc << SPARC_INSTR_ALIGNMENT_SHIFT);
239     reg(ic->arg[2]) = cpu->pc;
240    
241     cpu->delay_slot = TO_BE_DELAYED;
242     ic[1].f(cpu, ic+1);
243     cpu->n_translated_instrs ++;
244    
245     if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
246     /* Note: Must be non-delayed when jumping to the new pc: */
247     cpu->delay_slot = NOT_DELAYED;
248     cpu->pc = reg(ic->arg[0]) + reg(ic->arg[1]);
249     cpu_functioncall_trace(cpu, cpu->pc);
250     quick_pc_to_pointers(cpu);
251     } else
252     cpu->delay_slot = NOT_DELAYED;
253     }
254     X(retl_trace)
255     {
256     int low_pc = ((size_t)ic - (size_t)cpu->cd.sparc.cur_ic_page)
257     / sizeof(struct sparc_instr_call);
258     cpu->pc &= ~((SPARC_IC_ENTRIES_PER_PAGE-1)
259     << SPARC_INSTR_ALIGNMENT_SHIFT);
260     cpu->pc += (low_pc << SPARC_INSTR_ALIGNMENT_SHIFT);
261    
262     cpu->delay_slot = TO_BE_DELAYED;
263     ic[1].f(cpu, ic+1);
264     cpu->n_translated_instrs ++;
265    
266     if (!(cpu->delay_slot & EXCEPTION_IN_DELAY_SLOT)) {
267     /* Note: Must be non-delayed when jumping to the new pc: */
268     cpu->delay_slot = NOT_DELAYED;
269     cpu->pc = reg(ic->arg[0]) + (int32_t)ic->arg[1];
270     quick_pc_to_pointers(cpu);
271     cpu_functioncall_trace_return(cpu);
272     } else
273     cpu->delay_slot = NOT_DELAYED;
274     }
275    
276    
277     /*
278     * set: Set a register to a value (e.g. sethi).
279     *
280     * arg[0] = ptr to rd
281     * arg[1] = value (uint32_t)
282     */
283     X(set)
284     {
285     reg(ic->arg[0]) = (uint32_t)ic->arg[1];
286     }
287    
288    
289     /*
290     * Computational/arithmetic instructions:
291     *
292     * arg[0] = ptr to rs1
293     * arg[1] = ptr to rs2 or an immediate value (int32_t)
294     * arg[2] = ptr to rd
295     */
296     X(add) { reg(ic->arg[2]) = reg(ic->arg[0]) + reg(ic->arg[1]); }
297     X(add_imm) { reg(ic->arg[2]) = reg(ic->arg[0]) + (int32_t)ic->arg[1]; }
298     X(and) { reg(ic->arg[2]) = reg(ic->arg[0]) & reg(ic->arg[1]); }
299     X(and_imm) { reg(ic->arg[2]) = reg(ic->arg[0]) & (int32_t)ic->arg[1]; }
300     X(or) { reg(ic->arg[2]) = reg(ic->arg[0]) | reg(ic->arg[1]); }
301     X(or_imm) { reg(ic->arg[2]) = reg(ic->arg[0]) | (int32_t)ic->arg[1]; }
302     X(xor) { reg(ic->arg[2]) = reg(ic->arg[0]) ^ reg(ic->arg[1]); }
303     X(xor_imm) { reg(ic->arg[2]) = reg(ic->arg[0]) ^ (int32_t)ic->arg[1]; }
304     X(sub) { reg(ic->arg[2]) = reg(ic->arg[0]) - reg(ic->arg[1]); }
305     X(sub_imm) { reg(ic->arg[2]) = reg(ic->arg[0]) - (int32_t)ic->arg[1]; }
306    
307     X(sll) { reg(ic->arg[2]) = (uint32_t)reg(ic->arg[0]) <<
308     (reg(ic->arg[1]) & 31); }
309     X(sllx) { reg(ic->arg[2]) = (uint64_t)reg(ic->arg[0]) <<
310     (reg(ic->arg[1]) & 63); }
311     X(sll_imm) { reg(ic->arg[2]) = (uint32_t)reg(ic->arg[0]) << ic->arg[1]; }
312     X(sllx_imm) { reg(ic->arg[2]) = (uint64_t)reg(ic->arg[0]) << ic->arg[1]; }
313    
314     X(srl) { reg(ic->arg[2]) = (uint32_t)reg(ic->arg[0]) >>
315     (reg(ic->arg[1]) & 31); }
316     X(srlx) { reg(ic->arg[2]) = (uint64_t)reg(ic->arg[0]) >>
317     (reg(ic->arg[1]) & 63); }
318     X(srl_imm) { reg(ic->arg[2]) = (uint32_t)reg(ic->arg[0]) >> ic->arg[1]; }
319     X(srlx_imm) { reg(ic->arg[2]) = (uint64_t)reg(ic->arg[0]) >> ic->arg[1]; }
320    
321     X(sra) { reg(ic->arg[2]) = (int32_t)reg(ic->arg[0]) >>
322     (reg(ic->arg[1]) & 31); }
323     X(srax) { reg(ic->arg[2]) = (int64_t)reg(ic->arg[0]) >>
324     (reg(ic->arg[1]) & 63); }
325     X(sra_imm) { reg(ic->arg[2]) = (int32_t)reg(ic->arg[0]) >> ic->arg[1]; }
326     X(srax_imm) { reg(ic->arg[2]) = (int64_t)reg(ic->arg[0]) >> ic->arg[1]; }
327    
328    
329     /*
330     * Subtract with ccr update:
331     *
332     * arg[0] = ptr to rs1
333     * arg[1] = ptr to rs2 or an immediate value (int32_t)
334     * arg[2] = ptr to rd
335     */
336     int32_t sparc_subcc32(struct cpu *cpu, int32_t rs1, int32_t rs2);
337     #ifdef MODE32
338     int32_t sparc_subcc32(struct cpu *cpu, int32_t rs1, int32_t rs2)
339     #else
340     int64_t sparc_subcc64(struct cpu *cpu, int64_t rs1, int64_t rs2)
341     #endif
342     {
343     int cc = 0, sign1 = 0, sign2 = 0, signd = 0, mask = SPARC_CCR_ICC_MASK;
344     MODE_int_t rd = rs1 - rs2;
345     if (rd == 0)
346     cc = SPARC_CCR_Z;
347     else if (rd < 0)
348     cc = SPARC_CCR_N, signd = 1;
349     if (rs1 < 0)
350     sign1 = 1;
351     if (rs2 < 0)
352     sign2 = 1;
353     if (sign1 != sign2 && sign1 != signd)
354     cc |= SPARC_CCR_V;
355     /* TODO: SPARC_CCR_C */
356     #ifndef MODE32
357     mask <<= SPARC_CCR_XCC_SHIFT;
358     cc <<= SPARC_CCR_XCC_SHIFT;
359     #endif
360     cpu->cd.sparc.ccr &= ~mask;
361     cpu->cd.sparc.ccr |= cc;
362     return rd;
363     }
364     X(subcc)
365     {
366     /* Like sub, but updates the ccr, and does both 32-bit and
367     64-bit comparison at the same time. */
368     MODE_int_t rs1 = reg(ic->arg[0]), rs2 = reg(ic->arg[1]), rd;
369     rd = sparc_subcc32(cpu, rs1, rs2);
370     #ifndef MODE32
371     rd = sparc_subcc64(cpu, rs1, rs2);
372     #endif
373     reg(ic->arg[2]) = rd;
374     }
375     X(subcc_imm)
376     {
377     MODE_int_t rs1 = reg(ic->arg[0]), rs2 = (int32_t)ic->arg[1], rd;
378     rd = sparc_subcc32(cpu, rs1, rs2);
379     #ifndef MODE32
380     rd = sparc_subcc64(cpu, rs1, rs2);
381     #endif
382     reg(ic->arg[2]) = rd;
383     }
384    
385    
386     /*
387     * rd: Read special register:
388     *
389     * arg[2] = ptr to rd
390     */
391     X(rd_psr)
392     {
393     reg(ic->arg[2]) = cpu->cd.sparc.psr;
394     }
395    
396    
397     /*
398     * wrpr: Write to privileged register
399     *
400     * arg[0] = ptr to rs1
401     * arg[1] = ptr to rs2 or an immediate value (int32_t)
402     */
403     X(wrpr_tick)
404     {
405     cpu->cd.sparc.tick = (uint32_t) (reg(ic->arg[0]) ^ reg(ic->arg[1]));
406     }
407     X(wrpr_tick_imm)
408     {
409     cpu->cd.sparc.tick = (uint32_t) (reg(ic->arg[0]) ^ (int32_t)ic->arg[1]);
410     }
411     X(wrpr_pil)
412     {
413     cpu->cd.sparc.pil = (reg(ic->arg[0]) ^ reg(ic->arg[1]))
414     & SPARC_PIL_MASK;
415     }
416     X(wrpr_pil_imm)
417     {
418     cpu->cd.sparc.pil = (reg(ic->arg[0]) ^ (int32_t)ic->arg[1])
419     & SPARC_PIL_MASK;
420     }
421     X(wrpr_pstate)
422     {
423     sparc_update_pstate(cpu, reg(ic->arg[0]) ^ reg(ic->arg[1]));
424     }
425     X(wrpr_pstate_imm)
426     {
427     sparc_update_pstate(cpu, reg(ic->arg[0]) ^ (int32_t)ic->arg[1]);
428     }
429    
430    
431     /*****************************************************************************/
432    
433    
434 dpavlin 14 X(end_of_page)
435     {
436     /* Update the PC: (offset 0, but on the next page) */
437     cpu->pc &= ~((SPARC_IC_ENTRIES_PER_PAGE-1) <<
438     SPARC_INSTR_ALIGNMENT_SHIFT);
439     cpu->pc += (SPARC_IC_ENTRIES_PER_PAGE <<
440     SPARC_INSTR_ALIGNMENT_SHIFT);
441    
442     /* Find the new physical page and update the translation pointers: */
443 dpavlin 24 quick_pc_to_pointers(cpu);
444 dpavlin 14
445     /* end_of_page doesn't count as an executed instruction: */
446     cpu->n_translated_instrs --;
447     }
448    
449    
450 dpavlin 24 X(end_of_page2)
451     {
452     /* Synchronize PC on the _second_ instruction on the next page: */
453     int low_pc = ((size_t)ic - (size_t)cpu->cd.sparc.cur_ic_page)
454     / sizeof(struct sparc_instr_call);
455     cpu->pc &= ~((SPARC_IC_ENTRIES_PER_PAGE-1)
456     << SPARC_INSTR_ALIGNMENT_SHIFT);
457     cpu->pc += (low_pc << SPARC_INSTR_ALIGNMENT_SHIFT);
458    
459     /* This doesn't count as an executed instruction. */
460     cpu->n_translated_instrs --;
461    
462     quick_pc_to_pointers(cpu);
463    
464     if (cpu->delay_slot == NOT_DELAYED)
465     return;
466    
467     fatal("end_of_page2: fatal error, we're in a delay slot\n");
468     exit(1);
469     }
470    
471    
472 dpavlin 14 /*****************************************************************************/
473    
474    
475     /*
476     * sparc_instr_to_be_translated():
477     *
478 dpavlin 24 * Translate an instruction word into a sparc_instr_call. ic is filled in with
479 dpavlin 14 * valid data for the translated instruction, or a "nothing" instruction if
480     * there was a translation failure. The newly translated instruction is then
481     * executed.
482     */
483     X(to_be_translated)
484     {
485 dpavlin 24 MODE_uint_t addr;
486     int low_pc;
487     int in_crosspage_delayslot = 0;
488 dpavlin 14 uint32_t iword;
489     unsigned char *page;
490     unsigned char ib[4];
491 dpavlin 24 int main_opcode, op2, rd, rs1, rs2, btype, asi, cc, p, use_imm, x64 = 0;
492     int32_t tmpi32, siconst;
493 dpavlin 20 /* void (*samepage_function)(struct cpu *, struct sparc_instr_call *);*/
494 dpavlin 14
495     /* Figure out the (virtual) address of the instruction: */
496     low_pc = ((size_t)ic - (size_t)cpu->cd.sparc.cur_ic_page)
497     / sizeof(struct sparc_instr_call);
498 dpavlin 24
499     /* Special case for branch with delayslot on the next page: */
500     if (cpu->delay_slot == TO_BE_DELAYED && low_pc == 0) {
501     /* fatal("[ delay-slot translation across page "
502     "boundary ]\n"); */
503     in_crosspage_delayslot = 1;
504     }
505    
506 dpavlin 14 addr = cpu->pc & ~((SPARC_IC_ENTRIES_PER_PAGE-1)
507     << SPARC_INSTR_ALIGNMENT_SHIFT);
508     addr += (low_pc << SPARC_INSTR_ALIGNMENT_SHIFT);
509     cpu->pc = addr;
510     addr &= ~((1 << SPARC_INSTR_ALIGNMENT_SHIFT) - 1);
511    
512     /* Read the instruction word from memory: */
513 dpavlin 24 #ifdef MODE32
514 dpavlin 14 page = cpu->cd.sparc.host_load[addr >> 12];
515 dpavlin 24 #else
516     {
517     const uint32_t mask1 = (1 << DYNTRANS_L1N) - 1;
518     const uint32_t mask2 = (1 << DYNTRANS_L2N) - 1;
519     const uint32_t mask3 = (1 << DYNTRANS_L3N) - 1;
520     uint32_t x1 = (addr >> (64-DYNTRANS_L1N)) & mask1;
521     uint32_t x2 = (addr >> (64-DYNTRANS_L1N-DYNTRANS_L2N)) & mask2;
522     uint32_t x3 = (addr >> (64-DYNTRANS_L1N-DYNTRANS_L2N-
523     DYNTRANS_L3N)) & mask3;
524     struct DYNTRANS_L2_64_TABLE *l2 = cpu->cd.sparc.l1_64[x1];
525     struct DYNTRANS_L3_64_TABLE *l3 = l2->l3[x2];
526     page = l3->host_load[x3];
527     }
528     #endif
529 dpavlin 14
530     if (page != NULL) {
531     /* fatal("TRANSLATION HIT!\n"); */
532 dpavlin 24 memcpy(ib, page + (addr & 0xffc), sizeof(ib));
533 dpavlin 14 } else {
534     /* fatal("TRANSLATION MISS!\n"); */
535     if (!cpu->memory_rw(cpu, cpu->mem, addr, ib,
536     sizeof(ib), MEM_READ, CACHE_INSTRUCTION)) {
537     fatal("to_be_translated(): "
538     "read failed: TODO\n");
539     goto bad;
540     }
541     }
542    
543 dpavlin 24 /* SPARC instruction words are always big-endian. Convert
544     to host order: */
545     iword = BE32_TO_HOST( *((uint32_t *)&ib[0]) );
546 dpavlin 14
547    
548     #define DYNTRANS_TO_BE_TRANSLATED_HEAD
549     #include "cpu_dyntrans.c"
550     #undef DYNTRANS_TO_BE_TRANSLATED_HEAD
551    
552    
553     /*
554     * Translate the instruction:
555     */
556    
557 dpavlin 24 main_opcode = iword >> 30;
558     rd = (iword >> 25) & 31;
559     btype = rd & (N_SPARC_BRANCH_TYPES - 1);
560     rs1 = (iword >> 14) & 31;
561     use_imm = (iword >> 13) & 1;
562     asi = (iword >> 5) & 0xff;
563     rs2 = iword & 31;
564     siconst = (int16_t)((iword & 0x1fff) << 3) >> 3;
565     op2 = (main_opcode == 0)? ((iword >> 22) & 7) : ((iword >> 19) & 0x3f);
566     cc = (iword >> 20) & 3;
567     p = (iword >> 19) & 1;
568 dpavlin 14
569     switch (main_opcode) {
570    
571 dpavlin 24 case 0: switch (op2) {
572    
573     case 2: /* branch (32-bit integer comparison) */
574     tmpi32 = (iword << 10);
575     tmpi32 >>= 8;
576     ic->arg[0] = (int32_t)tmpi32 + (addr & 0xffc);
577     /* rd contains the annul bit concatenated with 4 bits
578     of condition code: */
579     /* TODO: samepage */
580     switch (rd) {
581     case 0x08:/* ba */
582     ic->f = instr(ba);
583     break;
584     default:goto bad;
585     }
586     break;
587    
588     case 4: /* sethi */
589     ic->arg[0] = (size_t)&cpu->cd.sparc.r[rd];
590     ic->arg[1] = (iword & 0x3fffff) << 10;
591     ic->f = instr(set);
592     if (rd == SPARC_ZEROREG)
593     ic->f = instr(nop);
594     break;
595    
596     default:fatal("TODO: unimplemented op2=%i for main "
597     "opcode %i\n", op2, main_opcode);
598     goto bad;
599     }
600     break;
601    
602     case 1: /* call and link */
603     tmpi32 = (iword << 2);
604     ic->arg[0] = (int32_t)tmpi32;
605     ic->arg[1] = addr & 0xffc;
606     if (cpu->machine->show_trace_tree)
607     ic->f = instr(call_trace);
608     else
609     ic->f = instr(call);
610     /* TODO: samepage */
611     break;
612    
613     case 2: switch (op2) {
614    
615     case 0: /* add */
616     case 1: /* and */
617     case 2: /* or */
618     case 3: /* xor */
619     case 4: /* sub */
620     case 20:/* subcc (cmp) */
621     case 37:/* sll */
622     case 38:/* srl */
623     case 39:/* sra */
624     ic->arg[0] = (size_t)&cpu->cd.sparc.r[rs1];
625     ic->f = NULL;
626     if (use_imm) {
627     ic->arg[1] = siconst;
628     switch (op2) {
629     case 0: ic->f = instr(add_imm); break;
630     case 1: ic->f = instr(and_imm); break;
631     case 2: ic->f = instr(or_imm); break;
632     case 3: ic->f = instr(xor_imm); break;
633     case 4: ic->f = instr(sub_imm); break;
634     case 20:ic->f = instr(subcc_imm); break;
635     case 37:if (siconst & 0x1000) {
636     ic->f = instr(sllx_imm);
637     ic->arg[1] &= 63;
638     x64 = 1;
639     } else {
640     ic->f = instr(sll_imm);
641     ic->arg[1] &= 31;
642     }
643     break;
644     case 38:if (siconst & 0x1000) {
645     ic->f = instr(srlx_imm);
646     ic->arg[1] &= 63;
647     x64 = 1;
648     } else {
649     ic->f = instr(srl_imm);
650     ic->arg[1] &= 31;
651     }
652     break;
653     case 39:if (siconst & 0x1000) {
654     ic->f = instr(srax_imm);
655     ic->arg[1] &= 63;
656     x64 = 1;
657     } else {
658     ic->f = instr(sra_imm);
659     ic->arg[1] &= 31;
660     }
661     break;
662     }
663     } else {
664     ic->arg[1] = (size_t)&cpu->cd.sparc.r[rs2];
665     switch (op2) {
666     case 0: ic->f = instr(add); break;
667     case 1: ic->f = instr(and); break;
668     case 2: ic->f = instr(or); break;
669     case 3: ic->f = instr(xor); break;
670     case 4: ic->f = instr(sub); break;
671     case 20:ic->f = instr(subcc); break;
672     case 37:if (siconst & 0x1000) {
673     ic->f = instr(sllx);
674     x64 = 1;
675     } else
676     ic->f = instr(sll);
677     break;
678     case 38:if (siconst & 0x1000) {
679     ic->f = instr(srlx);
680     x64 = 1;
681     } else
682     ic->f = instr(srl);
683     break;
684     case 39:if (siconst & 0x1000) {
685     ic->f = instr(srax);
686     x64 = 1;
687     } else
688     ic->f = instr(sra);
689     break;
690     }
691     }
692     if (ic->f == NULL) {
693     fatal("TODO: Unimplemented instruction "
694     "(possibly missed use_imm impl.)\n");
695     goto bad;
696     }
697     ic->arg[2] = (size_t)&cpu->cd.sparc.r[rd];
698     if (rd == SPARC_ZEROREG) {
699     /* Opcodes which update the ccr should use
700     the scratch register instead of being
701     turned into a nop, when the zero register
702     is used as the destination: */
703     switch (op2) {
704     case 20:/* subcc */
705     ic->arg[2] = (size_t)
706     &cpu->cd.sparc.scratch;
707     break;
708     default:ic->f = instr(nop);
709     }
710     }
711     break;
712    
713     case 41:/* rd %psr,%gpr on pre-sparcv9 */
714     if (cpu->is_32bit) {
715     ic->f = instr(rd_psr);
716     ic->arg[2] = (size_t)&cpu->cd.sparc.r[rd];
717     if (rd == SPARC_ZEROREG)
718     ic->f = instr(nop);
719     } else {
720     fatal("opcode 2,41 not yet implemented"
721     " for 64-bit cpus\n");
722     goto bad;
723     }
724     break;
725    
726     case 48:/* wr (Note: works as xor) */
727     ic->arg[0] = (size_t)&cpu->cd.sparc.r[rs1];
728     if (use_imm) {
729     ic->arg[1] = siconst;
730     ic->f = instr(xor_imm);
731     } else {
732     ic->arg[1] = (size_t)&cpu->cd.sparc.r[rs2];
733     ic->f = instr(xor);
734     }
735     ic->arg[2] = (size_t) NULL;
736     switch (rd) {
737     case 0: ic->arg[2] = (size_t)&cpu->cd.sparc.y;
738     break;
739     case 6: ic->arg[2] = (size_t)&cpu->cd.sparc.fprs;
740     break;
741     case 0x17:
742     ic->arg[2] = (size_t)&cpu->cd.sparc.tick_cmpr;
743     break;
744     }
745     if (ic->arg[2] == (size_t)NULL) {
746     fatal("TODO: Unimplemented wr instruction, "
747     "rd = 0x%02x\n", rd);
748     goto bad;
749     }
750     break;
751    
752     case 50:/* wrpr (Note: works as xor) */
753     ic->arg[0] = (size_t)&cpu->cd.sparc.r[rs1];
754     ic->f = NULL;
755     if (use_imm) {
756     ic->arg[1] = siconst;
757     switch (rd) {
758     case 4: ic->f = instr(wrpr_tick_imm); break;
759     case 6: ic->f = instr(wrpr_pstate_imm); break;
760     case 8: ic->f = instr(wrpr_pil_imm); break;
761     }
762     } else {
763     ic->arg[1] = (size_t)&cpu->cd.sparc.r[rs2];
764     switch (rd) {
765     case 4: ic->f = instr(wrpr_tick); break;
766     case 6: ic->f = instr(wrpr_pstate); break;
767     case 8: ic->f = instr(wrpr_pil); break;
768     }
769     }
770     if (ic->f == NULL) {
771     fatal("TODO: Unimplemented wrpr instruction,"
772     " rd = 0x%02x\n", rd);
773     goto bad;
774     }
775     break;
776    
777     case 56:/* jump and link */
778     ic->arg[0] = (size_t)&cpu->cd.sparc.r[rs1];
779     ic->arg[2] = (size_t)&cpu->cd.sparc.r[rd];
780     if (rd == SPARC_ZEROREG)
781     ic->arg[2] = (size_t)&cpu->cd.sparc.scratch;
782    
783     if (use_imm) {
784     ic->arg[1] = siconst;
785     if (rd == SPARC_ZEROREG)
786     ic->f = instr(jmpl_imm_no_rd);
787     else
788     ic->f = instr(jmpl_imm);
789     } else {
790     ic->arg[1] = (size_t)&cpu->cd.sparc.r[rs2];
791     if (rd == SPARC_ZEROREG)
792     ic->f = instr(jmpl_reg_no_rd);
793     else
794     ic->f = instr(jmpl_reg);
795     }
796    
797     /* special trace case: */
798     if (cpu->machine->show_trace_tree) {
799     if (iword == 0x81c3e008)
800     ic->f = instr(retl_trace);
801     else {
802     if (use_imm)
803     ic->f = instr(jmpl_imm_trace);
804     else
805     ic->f = instr(jmpl_reg_trace);
806     }
807     }
808     break;
809    
810     default:fatal("TODO: unimplemented op2=%i for main "
811     "opcode %i\n", op2, main_opcode);
812     goto bad;
813     }
814     break;
815    
816     default:fatal("TODO: unimplemented main opcode %i\n", main_opcode);
817     goto bad;
818 dpavlin 14 }
819    
820    
821 dpavlin 24 if (x64 && cpu->is_32bit) {
822     fatal("TODO: 64-bit instr on 32-bit cpu\n");
823     goto bad;
824     }
825    
826    
827 dpavlin 14 #define DYNTRANS_TO_BE_TRANSLATED_TAIL
828     #include "cpu_dyntrans.c"
829     #undef DYNTRANS_TO_BE_TRANSLATED_TAIL
830     }
831    

  ViewVC Help
Powered by ViewVC 1.1.26