/[gxemul]/trunk/src/cpu_ppc_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/cpu_ppc_instr.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 12 - (hide annotations)
Mon Oct 8 16:18:38 2007 UTC (16 years, 6 months ago) by dpavlin
File MIME type: text/plain
File size: 38974 byte(s)
++ trunk/HISTORY	(local)
$Id: HISTORY,v 1.905 2005/08/16 09:16:24 debug Exp $
20050628	Continuing the work on the ARM translation engine. end_of_page
		works. Experimenting with load/store translation caches
		(virtual -> physical -> host).
20050629	More ARM stuff (memory access translation cache, mostly). This
		might break a lot of stuff elsewhere, probably some MIPS-
		related translation things.
20050630	Many load/stores are now automatically generated and included
		into cpu_arm_instr.c; 1024 functions in total (!).
		Fixes based on feedback from Alec Voropay: only print 8 hex
		digits instead of 16 in some cases when emulating 32-bit
		machines; similar 8 vs 16 digit fix for breakpoint addresses;
		4Kc has 16 TLB entries, not 48; the MIPS config select1
		register is now printed with "reg ,0".
		Also changing many other occurances of 16 vs 8 digit output.
		Adding cache associativity fields to mips_cpu_types.h; updating
		some other cache fields; making the output of
		mips_cpu_dumpinfo() look nicer.
		Generalizing the bintrans stuff for device accesses to also
		work with the new translation system. (This might also break
		some MIPS things.)
		Adding multi-load/store instructions to the ARM disassembler
		and the translator, and some optimizations of various kinds.
20050701	Adding a simple dev_disk (it can read/write sectors from
		disk images).
20050712	Adding dev_ether (a simple ethernet send/receive device).
		Debugger command "ninstrs" for toggling show_nr_of_instructions
		during runtime.
		Removing the framebuffer logo.
20050713	Continuing on dev_ether.
		Adding a dummy cpu_alpha (again).
20050714	More work on cpu_alpha.
20050715	More work on cpu_alpha. Many instructions work, enough to run
		a simple framebuffer fill test (similar to the ARM test).
20050716	More Alpha stuff.
20050717	Minor updates (Alpha stuff).
20050718	Minor updates (Alpha stuff).
20050719	Generalizing some Alpha instructions.
20050720	More Alpha-related updates.
20050721	Continuing on cpu_alpha. Importing rpb.h from NetBSD/alpha.
20050722	Alpha-related updates: userland stuff (Hello World using
		write() compiled statically for FreeBSD/Alpha runs fine), and
		more instructions are now implemented.
20050723	Fixing ldq_u and stq_u.
		Adding more instructions (conditional moves, masks, extracts,
		shifts).
20050724	More FreeBSD/Alpha userland stuff, and adding some more
		instructions (inserts).
20050725	Continuing on the Alpha stuff. (Adding dummy ldt/stt.)
		Adding a -A command line option to turn off alignment checks
		in some cases (for translated code).
		Trying to remove the old bintrans code which updated the pc
		and nr_of_executed_instructions for every instruction.
20050726	Making another attempt att removing the pc/nr of instructions
		code. This time it worked, huge performance increase for
		artificial test code, but performance loss for real-world
		code :-( so I'm scrapping that code for now.
		Tiny performance increase on Alpha (by using ret instead of
		jmp, to play nice with the Alpha's branch prediction) for the
		old MIPS bintrans backend.
20050727	Various minor fixes and cleanups.
20050728	Switching from a 2-level virtual to host/physical translation
		system for ARM emulation, to a 1-level translation.
		Trying to switch from 2-level to 1-level for the MIPS bintrans
		system as well (Alpha only, so far), but there is at least one
		problem: caches and/or how they work with device mappings.
20050730	Doing the 2-level to 1-level conversion for the i386 backend.
		The cache/device bug is still there for R2K/3K :(
		Various other minor updates (Malta etc).
		The mc146818 clock now updates the UIP bit in a way which works
		better with Linux for at least sgimips and Malta emulation.
		Beginning the work on refactoring the dyntrans system.
20050731	Continuing the dyntrans refactoring.
		Fixing a small but serious host alignment bug in memory_rw.
		Adding support for big-endian load/stores to the i386 bintrans
		backend.
		Another minor i386 bintrans backend update: stores from the
		zero register are now one (or two) loads shorter.
		The slt and sltu instructions were incorrectly implemented for
		the i386 backend; only using them for 32-bit mode for now.
20050801	Continuing the dyntrans refactoring.
		Cleanup of the ns16550 serial controller (removing unnecessary
		code).
		Bugfix (memory corruption bug) in dev_gt, and a patch/hack from
		Alec Voropay for Linux/Malta.
20050802	More cleanup/refactoring of the dyntrans subsystem: adding
		phys_page pointers to the lookup tables, for quick jumps
		between translated pages.
		Better fix for the ns16550 device (but still no real FIFO
		functionality).
		Converting cpu_ppc to the new dyntrans system. This means that
		I will have to start from scratch with implementing each
		instruction, and figure out how to implement dual 64/32-bit
		modes etc.
		Removing the URISC CPU family, because it was useless.
20050803	When selecting a machine type, the main type can now be omitted
		if the subtype name is unique. (I.e. -E can be omitted.)
		Fixing a dyntrans/device update bug. (Writes to offset 0 of
		a device could sometimes go unnoticed.)
		Adding an experimental "instruction combination" hack for
		ARM for memset-like byte fill loops.
20050804	Minor progress on cpu_alpha and related things.
		Finally fixing the MIPS dmult/dmultu bugs.
		Fixing some minor TODOs.
20050805	Generalizing the 8259 PIC. It now also works with Cobalt
		and evbmips emulation, in addition to the x86 hack.
		Finally converting the ns16550 device to use devinit.
		Continuing the work on the dyntrans system. Thinking about
		how to add breakpoints.
20050806	More dyntrans updates. Breakpoints seem to work now.
20050807	Minor updates: cpu_alpha and related things; removing
		dev_malta (as it isn't used any more).
		Dyntrans: working on general "show trace tree" support.
		The trace tree stuff now works with both the old MIPS code and
		with newer dyntrans modes. :)
		Continuing on Alpha-related stuff (trying to get *BSD to boot
		a bit further, adding more instructions, etc).
20050808	Adding a dummy IA64 cpu family, and continuing the refactoring
		of the dyntrans system.
		Removing the regression test stuff, because it was more or
		less useless.
		Adding loadlinked/storeconditional type instructions to the
		Alpha emulation. (Needed for Linux/alpha. Not very well tested
		yet.)
20050809	The function call trace tree now prints a per-function nr of
		arguments. (Semi-meaningless, since that data isn't read yet
		from the ELFs; some hardcoded symbols such as memcpy() and
		strlen() work fine, though.)
		More dyntrans refactoring; taking out more of the things that
		are common to all cpu families.
20050810	Working on adding support for "dual mode" for PPC dyntrans
		(i.e. both 64-bit and 32-bit modes).
		(Re)adding some simple PPC instructions.
20050811	Adding a dummy M68K cpu family. The dyntrans system isn't ready
		for variable-length ISAs yet, so it's completely bogus so far.
		Re-adding more PPC instructions.
		Adding a hack to src/file.c which allows OpenBSD/mac68k a.out
		kernels to be loaded.
		Beginning to add PPC loads/stores. So far they only work in
		32-bit mode.
20050812	The configure file option "add_remote" now accepts symbolic
		host names, in addition to numeric IPv4 addresses.
		Re-adding more PPC instructions.
20050814	Continuing to port back more PPC instructions.
		Found and fixed the cache/device write-update bug for 32-bit
		MIPS bintrans. :-)
		Triggered a really weird and annoying bug in Compaq's C
		compiler; ccc sometimes outputs code which loads from an
		address _before_ checking whether the pointer was NULL or not.
		(I'm not sure how to handle this problem.)
20050815	Removing all of the old x86 instruction execution code; adding
		a new (dummy) dyntrans module for x86.
		Taking the first steps to extend the dyntrans system to support
		variable-length instructions.
		Slowly preparing for the next release.
20050816	Adding a dummy SPARC cpu module.
		Minor updates (documentation etc) for the release.

==============  RELEASE 0.3.5  ==============


1 dpavlin 12 /*
2     * Copyright (C) 2005 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_ppc_instr.c,v 1.28 2005/08/14 23:44:22 debug Exp $
29     *
30     * POWER/PowerPC 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     * invalid: To catch bugs.
49     */
50     X(invalid)
51     {
52     fatal("INTERNAL ERROR\n");
53     exit(1);
54     }
55    
56    
57     /*
58     * addi: Add immediate.
59     *
60     * arg[0] = pointer to source uint64_t
61     * arg[1] = immediate value (int32_t or larger)
62     * arg[2] = pointer to destination uint64_t
63     */
64     X(addi)
65     {
66     reg(ic->arg[2]) = reg(ic->arg[0]) + (int32_t)ic->arg[1];
67     }
68    
69    
70     /*
71     * andi_dot: AND immediate, update CR.
72     *
73     * arg[0] = pointer to source uint64_t
74     * arg[1] = immediate value (uint32_t)
75     * arg[2] = pointer to destination uint64_t
76     */
77     X(andi_dot)
78     {
79     MODE_uint_t tmp = reg(ic->arg[0]) & (uint32_t)ic->arg[1];
80     reg(ic->arg[2]) = tmp;
81     update_cr0(cpu, tmp);
82     }
83    
84    
85     /*
86     * addic: Add immediate, Carry.
87     *
88     * arg[0] = pointer to source uint64_t
89     * arg[1] = immediate value (int32_t or larger)
90     * arg[2] = pointer to destination uint64_t
91     */
92     X(addic)
93     {
94     /* TODO/NOTE: Only for 32-bit mode, so far! */
95     uint64_t tmp = (int32_t)reg(ic->arg[0]);
96     uint64_t tmp2 = tmp;
97    
98     tmp2 += (int32_t)ic->arg[1];
99    
100     /* NOTE: CA is never cleared, just set. */
101     /* TODO: Is this correct? */
102     if ((tmp2 >> 32) != (tmp >> 32))
103     cpu->cd.ppc.xer |= PPC_XER_CA;
104    
105     reg(ic->arg[2]) = (uint32_t)tmp2;
106     }
107    
108    
109     /*
110     * subfic: Subtract from immediate, Carry.
111     *
112     * arg[0] = pointer to source uint64_t
113     * arg[1] = immediate value (int32_t or larger)
114     * arg[2] = pointer to destination uint64_t
115     */
116     X(subfic)
117     {
118     /* TODO/NOTE: Only for 32-bit mode, so far! */
119     uint64_t tmp = (int32_t)(~reg(ic->arg[0]));
120     uint64_t tmp2 = tmp;
121    
122     tmp2 += (int32_t)ic->arg[1] + 1;
123    
124     /* NOTE: CA is never cleared, just set. TODO: Is this right? */
125     /* TODO: Is this correct? */
126     if ((tmp2 >> 32) != (tmp >> 32))
127     cpu->cd.ppc.xer |= PPC_XER_CA;
128    
129     reg(ic->arg[2]) = (uint32_t)tmp2;
130     }
131    
132    
133     /*
134     * addic_dot: Add immediate, Carry.
135     *
136     * arg[0] = pointer to source uint64_t
137     * arg[1] = immediate value (int32_t or larger)
138     * arg[2] = pointer to destination uint64_t
139     */
140     X(addic_dot)
141     {
142     /* TODO/NOTE: Only for 32-bit mode, so far! */
143     uint64_t tmp = (uint32_t)reg(ic->arg[0]);
144     uint64_t tmp2 = tmp;
145    
146     tmp2 += (int32_t)ic->arg[1];
147    
148     /* NOTE: CA is never cleared, just set. */
149     /* TODO: Is this correct? */
150     if ((tmp2 >> 32) != (tmp >> 32))
151     cpu->cd.ppc.xer |= PPC_XER_CA;
152    
153     reg(ic->arg[2]) = (uint32_t)tmp2;
154     update_cr0(cpu, tmp2);
155     }
156    
157    
158     /*
159     * bclr: Branch Conditional to Link Register
160     *
161     * arg[0] = bo
162     * arg[1] = bi
163     * arg[2] = bh
164     */
165     X(bclr)
166     {
167     int bo = ic->arg[0], bi = ic->arg[1] /* , bh = ic->arg[2] */;
168     int ctr_ok, cond_ok;
169     MODE_uint_t tmp, addr = cpu->cd.ppc.lr;
170     if (!(bo & 4))
171     cpu->cd.ppc.ctr --;
172     ctr_ok = (bo >> 2) & 1;
173     tmp = cpu->cd.ppc.ctr;
174     ctr_ok |= ( (tmp != 0) ^ ((bo >> 1) & 1) );
175     cond_ok = (bo >> 4) & 1;
176     cond_ok |= ( ((bo >> 3) & 1) == ((cpu->cd.ppc.cr >> (31-bi)) & 1) );
177     if (ctr_ok && cond_ok) {
178     if (cpu->machine->show_trace_tree)
179     cpu_functioncall_trace_return(cpu);
180     cpu->pc = addr & ~3;
181     /* Find the new physical page and update pointers: */
182     ppc_pc_to_pointers(cpu);
183     }
184     }
185    
186    
187     /*
188     * b: Branch (to a different translated page)
189     *
190     * arg[0] = relative offset (as an int32_t)
191     */
192     X(b)
193     {
194     uint64_t low_pc;
195    
196     /* Calculate new PC from this instruction + arg[0] */
197     low_pc = ((size_t)ic - (size_t)
198     cpu->cd.ppc.cur_ic_page) / sizeof(struct ppc_instr_call);
199     cpu->pc &= ~((PPC_IC_ENTRIES_PER_PAGE-1) << 2);
200     cpu->pc += (low_pc << 2);
201     cpu->pc += (int32_t)ic->arg[0];
202    
203     /* Find the new physical page and update the translation pointers: */
204     ppc_pc_to_pointers(cpu);
205     }
206    
207    
208     /*
209     * bc: Branch Conditional (to a different translated page)
210     *
211     * arg[0] = relative offset (as an int32_t)
212     * arg[1] = bo
213     * arg[2] = bi
214     */
215     X(bc)
216     {
217     MODE_uint_t tmp;
218     int ctr_ok, cond_ok, bi = ic->arg[2], bo = ic->arg[1];
219     if (!(bo & 4))
220     cpu->cd.ppc.ctr --;
221     ctr_ok = (bo >> 2) & 1;
222     tmp = cpu->cd.ppc.ctr;
223     ctr_ok |= ( (tmp != 0) ^ ((bo >> 1) & 1) );
224     cond_ok = (bo >> 4) & 1;
225     cond_ok |= ( ((bo >> 3) & 1) ==
226     ((cpu->cd.ppc.cr >> (31-bi)) & 1) );
227     if (ctr_ok && cond_ok)
228     instr(b)(cpu,ic);
229     }
230    
231    
232     /*
233     * b_samepage: Branch (to within the same translated page)
234     *
235     * arg[0] = pointer to new ppc_instr_call
236     */
237     X(b_samepage)
238     {
239     cpu->cd.ppc.next_ic = (struct ppc_instr_call *) ic->arg[0];
240     }
241    
242    
243     /*
244     * bc_samepage: Branch Conditional (to within the same page)
245     *
246     * arg[0] = new ic ptr
247     * arg[1] = bo
248     * arg[2] = bi
249     */
250     X(bc_samepage)
251     {
252     MODE_uint_t tmp;
253     int ctr_ok, cond_ok, bi = ic->arg[2], bo = ic->arg[1];
254     if (!(bo & 4))
255     cpu->cd.ppc.ctr --;
256     ctr_ok = (bo >> 2) & 1;
257     tmp = cpu->cd.ppc.ctr;
258     ctr_ok |= ( (tmp != 0) ^ ((bo >> 1) & 1) );
259     cond_ok = (bo >> 4) & 1;
260     cond_ok |= ( ((bo >> 3) & 1) ==
261     ((cpu->cd.ppc.cr >> (31-bi)) & 1) );
262     if (ctr_ok && cond_ok)
263     instr(b_samepage)(cpu,ic);
264     }
265    
266    
267     /*
268     * bl: Branch and Link (to a different translated page)
269     *
270     * arg[0] = relative offset (as an int32_t)
271     */
272     X(bl)
273     {
274     uint32_t low_pc;
275    
276     /* Calculate LR: */
277     low_pc = ((size_t)cpu->cd.ppc.next_ic - (size_t)
278     cpu->cd.ppc.cur_ic_page) / sizeof(struct ppc_instr_call);
279     cpu->cd.ppc.lr = cpu->pc & ~((PPC_IC_ENTRIES_PER_PAGE-1) << 2);
280     cpu->cd.ppc.lr += (low_pc << 2);
281    
282     /* Calculate new PC from this instruction + arg[0] */
283     low_pc = ((size_t)ic - (size_t)
284     cpu->cd.ppc.cur_ic_page) / sizeof(struct ppc_instr_call);
285     cpu->pc &= ~((PPC_IC_ENTRIES_PER_PAGE-1) << 2);
286     cpu->pc += (low_pc << 2);
287     cpu->pc += (int32_t)ic->arg[0];
288    
289     /* Find the new physical page and update the translation pointers: */
290     ppc_pc_to_pointers(cpu);
291     }
292    
293    
294     /*
295     * bl_trace: Branch and Link (to a different translated page) (with trace)
296     *
297     * arg[0] = relative offset (as an int32_t)
298     */
299     X(bl_trace)
300     {
301     uint32_t low_pc;
302    
303     /* Calculate LR: */
304     low_pc = ((size_t)cpu->cd.ppc.next_ic - (size_t)
305     cpu->cd.ppc.cur_ic_page) / sizeof(struct ppc_instr_call);
306     cpu->cd.ppc.lr = cpu->pc & ~((PPC_IC_ENTRIES_PER_PAGE-1) << 2);
307     cpu->cd.ppc.lr += (low_pc << 2);
308    
309     /* Calculate new PC from this instruction + arg[0] */
310     low_pc = ((size_t)ic - (size_t)
311     cpu->cd.ppc.cur_ic_page) / sizeof(struct ppc_instr_call);
312     cpu->pc &= ~((PPC_IC_ENTRIES_PER_PAGE-1) << 2);
313     cpu->pc += (low_pc << 2);
314     cpu->pc += (int32_t)ic->arg[0];
315    
316     cpu_functioncall_trace(cpu, cpu->pc);
317    
318     /* Find the new physical page and update the translation pointers: */
319     ppc_pc_to_pointers(cpu);
320     }
321    
322    
323     /*
324     * bl_samepage: Branch and Link (to within the same translated page)
325     *
326     * arg[0] = pointer to new ppc_instr_call
327     */
328     X(bl_samepage)
329     {
330     uint32_t low_pc;
331    
332     /* Calculate LR: */
333     low_pc = ((size_t)cpu->cd.ppc.next_ic - (size_t)
334     cpu->cd.ppc.cur_ic_page) / sizeof(struct ppc_instr_call);
335     cpu->cd.ppc.lr = cpu->pc & ~((PPC_IC_ENTRIES_PER_PAGE-1) << 2);
336     cpu->cd.ppc.lr += (low_pc << 2);
337    
338     cpu->cd.ppc.next_ic = (struct ppc_instr_call *) ic->arg[0];
339     }
340    
341    
342     /*
343     * bl_samepage_trace: Branch and Link (to within the same translated page)
344     *
345     * arg[0] = pointer to new ppc_instr_call
346     */
347     X(bl_samepage_trace)
348     {
349     uint32_t low_pc;
350    
351     /* Calculate LR: */
352     low_pc = ((size_t)cpu->cd.ppc.next_ic - (size_t)
353     cpu->cd.ppc.cur_ic_page) / sizeof(struct ppc_instr_call);
354     cpu->cd.ppc.lr = cpu->pc & ~((PPC_IC_ENTRIES_PER_PAGE-1) << 2);
355     cpu->cd.ppc.lr += (low_pc << 2);
356    
357     cpu->cd.ppc.next_ic = (struct ppc_instr_call *) ic->arg[0];
358    
359     /* Calculate new PC (for the trace) */
360     low_pc = ((size_t)cpu->cd.ppc.next_ic - (size_t)
361     cpu->cd.ppc.cur_ic_page) / sizeof(struct ppc_instr_call);
362     cpu->pc &= ~((PPC_IC_ENTRIES_PER_PAGE-1) << 2);
363     cpu->pc += (low_pc << 2);
364     cpu_functioncall_trace(cpu, cpu->pc);
365     }
366    
367    
368     /*
369     * cmpd: Compare Doubleword
370     *
371     * arg[0] = ptr to ra
372     * arg[1] = ptr to rb
373     * arg[2] = bf
374     */
375     X(cmpd)
376     {
377     int64_t tmp = reg(ic->arg[0]), tmp2 = reg(ic->arg[1]);
378     int bf = ic->arg[2], c;
379     if (tmp < tmp2)
380     c = 8;
381     else if (tmp > tmp2)
382     c = 4;
383     else
384     c = 2;
385     c |= ((cpu->cd.ppc.xer >> 31) & 1); /* SO bit, copied from XER */
386     cpu->cd.ppc.cr &= ~(0xf << (28 - 4*bf));
387     cpu->cd.ppc.cr |= (c << (28 - 4*bf));
388     }
389    
390    
391     /*
392     * cmpld: Compare Doubleword, unsigned
393     *
394     * arg[0] = ptr to ra
395     * arg[1] = ptr to rb
396     * arg[2] = bf
397     */
398     X(cmpld)
399     {
400     uint64_t tmp = reg(ic->arg[0]), tmp2 = reg(ic->arg[1]);
401     int bf = ic->arg[2], c;
402     if (tmp < tmp2)
403     c = 8;
404     else if (tmp > tmp2)
405     c = 4;
406     else
407     c = 2;
408     c |= ((cpu->cd.ppc.xer >> 31) & 1); /* SO bit, copied from XER */
409     cpu->cd.ppc.cr &= ~(0xf << (28 - 4*bf));
410     cpu->cd.ppc.cr |= (c << (28 - 4*bf));
411     }
412    
413    
414     /*
415     * cmpdi: Compare Doubleword immediate
416     *
417     * arg[0] = ptr to ra
418     * arg[1] = int32_t imm
419     * arg[2] = bf
420     */
421     X(cmpdi)
422     {
423     int64_t tmp = reg(ic->arg[0]), imm = (int32_t)ic->arg[1];
424     int bf = ic->arg[2], c;
425     if (tmp < imm)
426     c = 8;
427     else if (tmp > imm)
428     c = 4;
429     else
430     c = 2;
431     c |= ((cpu->cd.ppc.xer >> 31) & 1); /* SO bit, copied from XER */
432     cpu->cd.ppc.cr &= ~(0xf << (28 - 4*bf));
433     cpu->cd.ppc.cr |= (c << (28 - 4*bf));
434     }
435    
436    
437     /*
438     * cmpldi: Compare Doubleword immediate, logical
439     *
440     * arg[0] = ptr to ra
441     * arg[1] = int32_t imm
442     * arg[2] = bf
443     */
444     X(cmpldi)
445     {
446     uint64_t tmp = reg(ic->arg[0]), imm = (uint32_t)ic->arg[1];
447     int bf = ic->arg[2], c;
448     if (tmp < imm)
449     c = 8;
450     else if (tmp > imm)
451     c = 4;
452     else
453     c = 2;
454     c |= ((cpu->cd.ppc.xer >> 31) & 1); /* SO bit, copied from XER */
455     cpu->cd.ppc.cr &= ~(0xf << (28 - 4*bf));
456     cpu->cd.ppc.cr |= (c << (28 - 4*bf));
457     }
458    
459    
460     /*
461     * cmpw: Compare Word
462     *
463     * arg[0] = ptr to ra
464     * arg[1] = ptr to rb
465     * arg[2] = bf
466     */
467     X(cmpw)
468     {
469     int32_t tmp = reg(ic->arg[0]), tmp2 = reg(ic->arg[1]);
470     int bf = ic->arg[2], c;
471     if (tmp < tmp2)
472     c = 8;
473     else if (tmp > tmp2)
474     c = 4;
475     else
476     c = 2;
477     c |= ((cpu->cd.ppc.xer >> 31) & 1); /* SO bit, copied from XER */
478     cpu->cd.ppc.cr &= ~(0xf << (28 - 4*bf));
479     cpu->cd.ppc.cr |= (c << (28 - 4*bf));
480     }
481    
482    
483     /*
484     * cmplw: Compare Word, unsigned
485     *
486     * arg[0] = ptr to ra
487     * arg[1] = ptr to rb
488     * arg[2] = bf
489     */
490     X(cmplw)
491     {
492     uint32_t tmp = reg(ic->arg[0]), tmp2 = reg(ic->arg[1]);
493     int bf = ic->arg[2], c;
494     if (tmp < tmp2)
495     c = 8;
496     else if (tmp > tmp2)
497     c = 4;
498     else
499     c = 2;
500     c |= ((cpu->cd.ppc.xer >> 31) & 1); /* SO bit, copied from XER */
501     cpu->cd.ppc.cr &= ~(0xf << (28 - 4*bf));
502     cpu->cd.ppc.cr |= (c << (28 - 4*bf));
503     }
504    
505    
506     /*
507     * cmpwi: Compare Word immediate
508     *
509     * arg[0] = ptr to ra
510     * arg[1] = int32_t imm
511     * arg[2] = bf
512     */
513     X(cmpwi)
514     {
515     int32_t tmp = reg(ic->arg[0]), imm = ic->arg[1];
516     int bf = ic->arg[2], c;
517     if (tmp < imm)
518     c = 8;
519     else if (tmp > imm)
520     c = 4;
521     else
522     c = 2;
523     c |= ((cpu->cd.ppc.xer >> 31) & 1); /* SO bit, copied from XER */
524     cpu->cd.ppc.cr &= ~(0xf << (28 - 4*bf));
525     cpu->cd.ppc.cr |= (c << (28 - 4*bf));
526     }
527    
528    
529     /*
530     * cmplwi: Compare Word immediate, logical
531     *
532     * arg[0] = ptr to ra
533     * arg[1] = int32_t imm
534     * arg[2] = bf
535     */
536     X(cmplwi)
537     {
538     uint32_t tmp = reg(ic->arg[0]), imm = ic->arg[1];
539     int bf = ic->arg[2], c;
540     if (tmp < imm)
541     c = 8;
542     else if (tmp > imm)
543     c = 4;
544     else
545     c = 2;
546     c |= ((cpu->cd.ppc.xer >> 31) & 1); /* SO bit, copied from XER */
547     cpu->cd.ppc.cr &= ~(0xf << (28 - 4*bf));
548     cpu->cd.ppc.cr |= (c << (28 - 4*bf));
549     }
550    
551    
552     /*
553     * rlwinm:
554     *
555     * arg[0] = ptr to rs
556     * arg[1] = ptr to ra
557     * arg[2] = copy of the instruction word
558     */
559     X(rlwinm)
560     {
561     MODE_uint_t tmp = reg(ic->arg[0]), ra = 0;
562     uint32_t iword = ic->arg[2];
563     int sh, mb, me, rc;
564    
565     sh = (iword >> 11) & 31;
566     mb = (iword >> 6) & 31;
567     me = (iword >> 1) & 31;
568     rc = iword & 1;
569    
570     /* TODO: Fix this, its performance is awful: */
571     while (sh-- != 0) {
572     int b = (tmp >> 31) & 1;
573     tmp = (tmp << 1) | b;
574     }
575     for (;;) {
576     uint64_t mask;
577     mask = (uint64_t)1 << (31-mb);
578     ra |= (tmp & mask);
579     if (mb == me)
580     break;
581     mb ++;
582     if (mb == 32)
583     mb = 0;
584     }
585    
586     reg(ic->arg[1]) = ra;
587     if (rc)
588     update_cr0(cpu, ra);
589     }
590    
591    
592     /*
593     * srawi:
594     *
595     * arg[0] = ptr to rs
596     * arg[1] = ptr to ra
597     * arg[2] = sh (shift amount)
598     */
599     X(srawi)
600     {
601     uint32_t tmp = reg(ic->arg[0]);
602     int i = 0, j = 0, sh = ic->arg[2];
603    
604     cpu->cd.ppc.xer &= ~PPC_XER_CA;
605     if (tmp & 0x80000000)
606     i = 1;
607     while (sh-- > 0) {
608     if (tmp & 1)
609     j ++;
610     tmp >>= 1;
611     if (tmp & 0x40000000)
612     tmp |= 0x80000000;
613     }
614     if (i && j>0)
615     cpu->cd.ppc.xer |= PPC_XER_CA;
616     reg(ic->arg[1]) = (int64_t)(int32_t)tmp;
617     }
618     X(srawi_dot) { instr(srawi)(cpu,ic); update_cr0(cpu, reg(ic->arg[1])); }
619    
620    
621     /*
622     * crxor: Condition Register XOR
623     *
624     * arg[0] = copy of the instruction word
625     */
626     X(crxor)
627     {
628     uint32_t iword = ic->arg[0];
629     int bt = (iword >> 21) & 31;
630     int ba = (iword >> 16) & 31;
631     int bb = (iword >> 11) & 31;
632     ba = (cpu->cd.ppc.cr >> (31-ba)) & 1;
633     bb = (cpu->cd.ppc.cr >> (31-bb)) & 1;
634     cpu->cd.ppc.cr &= ~(1 << (31-bt));
635     if (ba ^ bb)
636     cpu->cd.ppc.cr |= (1 << (31-bt));
637     }
638    
639    
640     /*
641     * mflr, etc: Move from Link Register etc.
642     *
643     * arg[0] = pointer to destination register
644     */
645     X(mflr) { reg(ic->arg[0]) = cpu->cd.ppc.lr; }
646     /* TODO: Check privilege level for mfsprg* */
647     X(mfsprg0) { reg(ic->arg[0]) = cpu->cd.ppc.sprg0; }
648     X(mfsprg1) { reg(ic->arg[0]) = cpu->cd.ppc.sprg1; }
649     X(mfsprg2) { reg(ic->arg[0]) = cpu->cd.ppc.sprg2; }
650     X(mfsprg3) { reg(ic->arg[0]) = cpu->cd.ppc.sprg3; }
651    
652    
653     /*
654     * mtlr etc.: Move to Link Register (or other special register)
655     *
656     * arg[0] = pointer to source register
657     */
658     X(mtlr) { cpu->cd.ppc.lr = reg(ic->arg[0]); }
659     /* TODO: Check privilege level for mtsprg* */
660     X(mtsprg0) { cpu->cd.ppc.sprg0 = reg(ic->arg[0]); }
661     X(mtsprg1) { cpu->cd.ppc.sprg1 = reg(ic->arg[0]); }
662     X(mtsprg2) { cpu->cd.ppc.sprg2 = reg(ic->arg[0]); }
663     X(mtsprg3) { cpu->cd.ppc.sprg3 = reg(ic->arg[0]); }
664    
665    
666     /*
667     * mfcr: Move From Condition Register
668     *
669     * arg[0] = pointer to destination register
670     */
671     X(mfcr)
672     {
673     reg(ic->arg[0]) = cpu->cd.ppc.cr;
674     }
675    
676    
677     /*
678     * mfmsr: Move From MSR
679     *
680     * arg[0] = pointer to destination register
681     */
682     X(mfmsr)
683     {
684     reg_access_msr(cpu, (uint64_t*)ic->arg[0], 0);
685     }
686    
687    
688     /*
689     * mtmsr: Move To MSR
690     *
691     * arg[0] = pointer to source register
692     */
693     X(mtmsr)
694     {
695     reg_access_msr(cpu, (uint64_t*)ic->arg[0], 1);
696     }
697    
698    
699     /*
700     * mtcrf: Move To Condition Register Fields
701     *
702     * arg[0] = pointer to source register
703     */
704     X(mtcrf)
705     {
706     cpu->cd.ppc.cr &= ~ic->arg[1];
707     cpu->cd.ppc.cr |= (reg(ic->arg[0]) & ic->arg[1]);
708     }
709    
710    
711     /*
712     * mulli: Multiply Low Immediate.
713     *
714     * arg[0] = pointer to source register ra
715     * arg[1] = int32_t immediate
716     * arg[2] = pointer to destination register rt
717     */
718     X(mulli)
719     {
720     reg(ic->arg[2]) = (uint32_t)(reg(ic->arg[0]) * ic->arg[1]);
721     }
722    
723    
724     /*
725     * Shifts, and, or, xor, etc.
726     *
727     * arg[0] = pointer to source register rs
728     * arg[1] = pointer to source register rb
729     * arg[2] = pointer to destination register ra
730     */
731     X(slw) { reg(ic->arg[2]) = (uint64_t)reg(ic->arg[0])
732     << (reg(ic->arg[1]) & 63); }
733     X(slw_dot) { reg(ic->arg[2]) = (uint64_t)reg(ic->arg[0])
734     << (reg(ic->arg[1]) & 63);
735     update_cr0(cpu, reg(ic->arg[2])); }
736     X(sraw) { reg(ic->arg[2]) = (int64_t)reg(ic->arg[0])
737     >> (reg(ic->arg[1]) & 63); }
738     X(sraw_dot) { reg(ic->arg[2]) = (int64_t)reg(ic->arg[0])
739     >> (reg(ic->arg[1]) & 63);
740     update_cr0(cpu, reg(ic->arg[2])); }
741     X(and) { reg(ic->arg[2]) = reg(ic->arg[0]) & reg(ic->arg[1]); }
742     X(and_dot) { reg(ic->arg[2]) = reg(ic->arg[0]) & reg(ic->arg[1]);
743     update_cr0(cpu, reg(ic->arg[2])); }
744     X(andc) { reg(ic->arg[2]) = reg(ic->arg[0]) & (~reg(ic->arg[1])); }
745     X(andc_dot) { reg(ic->arg[2]) = reg(ic->arg[0]) & (~reg(ic->arg[1]));
746     update_cr0(cpu, reg(ic->arg[2])); }
747     X(nor) { reg(ic->arg[2]) = ~(reg(ic->arg[0]) | reg(ic->arg[1])); }
748     X(nor_dot) { reg(ic->arg[2]) = ~(reg(ic->arg[0]) | reg(ic->arg[1]));
749     update_cr0(cpu, reg(ic->arg[2])); }
750     X(or) { reg(ic->arg[2]) = reg(ic->arg[0]) | reg(ic->arg[1]); }
751     X(or_dot) { reg(ic->arg[2]) = reg(ic->arg[0]) | reg(ic->arg[1]);
752     update_cr0(cpu, reg(ic->arg[2])); }
753     X(orc) { reg(ic->arg[2]) = reg(ic->arg[0]) | (~reg(ic->arg[1])); }
754     X(orc_dot) { reg(ic->arg[2]) = reg(ic->arg[0]) | (~reg(ic->arg[1]));
755     update_cr0(cpu, reg(ic->arg[2])); }
756     X(xor) { reg(ic->arg[2]) = reg(ic->arg[0]) ^ reg(ic->arg[1]); }
757     X(xor_dot) { reg(ic->arg[2]) = reg(ic->arg[0]) ^ reg(ic->arg[1]);
758     update_cr0(cpu, reg(ic->arg[2])); }
759    
760    
761     /*
762     * neg:
763     *
764     * arg[0] = pointer to source register ra
765     * arg[1] = pointer to destination register rt
766     */
767     X(neg) { reg(ic->arg[1]) = ~reg(ic->arg[0]) + 1; }
768     X(neg_dot) { reg(ic->arg[1]) = ~reg(ic->arg[0]) + 1;
769     update_cr0(cpu, reg(ic->arg[1])); }
770    
771    
772     /*
773     * mullw, mulhw[u], divw[u]:
774     *
775     * arg[0] = pointer to source register ra
776     * arg[1] = pointer to source register rb
777     * arg[2] = pointer to destination register rt
778     */
779     X(mullw)
780     {
781     int32_t sum = (int32_t)reg(ic->arg[0]) * (int32_t)reg(ic->arg[1]);
782     reg(ic->arg[2]) = (int32_t)sum;
783     }
784     X(mulhw)
785     {
786     int64_t sum;
787     sum = (int64_t)(int32_t)reg(ic->arg[0])
788     * (int64_t)(int32_t)reg(ic->arg[1]);
789     reg(ic->arg[2]) = sum >> 32;
790     }
791     X(mulhwu)
792     {
793     uint64_t sum;
794     sum = (uint64_t)(uint32_t)reg(ic->arg[0])
795     * (uint64_t)(uint32_t)reg(ic->arg[1]);
796     reg(ic->arg[2]) = sum >> 32;
797     }
798     X(divw)
799     {
800     int32_t a = reg(ic->arg[0]), b = reg(ic->arg[1]);
801     int32_t sum;
802     if (b == 0)
803     sum = 0;
804     else
805     sum = a / b;
806     reg(ic->arg[2]) = (uint32_t)sum;
807     }
808     X(divwu)
809     {
810     uint32_t a = reg(ic->arg[0]), b = reg(ic->arg[1]);
811     uint32_t sum;
812     if (b == 0)
813     sum = 0;
814     else
815     sum = a / b;
816     reg(ic->arg[2]) = sum;
817     }
818    
819    
820     /*
821     * add: Add.
822     *
823     * arg[0] = pointer to source register ra
824     * arg[1] = pointer to source register rb
825     * arg[2] = pointer to destination register rt
826     */
827     X(add)
828     {
829     reg(ic->arg[2]) = reg(ic->arg[0]) + reg(ic->arg[1]);
830     }
831    
832    
833     /*
834     * addc: Add carrying.
835     *
836     * arg[0] = pointer to source register ra
837     * arg[1] = pointer to source register rb
838     * arg[2] = pointer to destination register rt
839     */
840     X(addc)
841     {
842     /* TODO: this only works in 32-bit mode */
843     uint64_t tmp = (uint32_t)reg(ic->arg[0]);
844     uint64_t tmp2 = tmp;
845     cpu->cd.ppc.xer &= PPC_XER_CA;
846     tmp += (uint32_t)reg(ic->arg[1]);
847     if ((tmp >> 32) == (tmp2 >> 32))
848     cpu->cd.ppc.xer |= PPC_XER_CA;
849     reg(ic->arg[2]) = (uint32_t)tmp;
850     }
851    
852    
853     /*
854     * adde: Add extended, etc.
855     *
856     * arg[0] = pointer to source register ra
857     * arg[1] = pointer to source register rb
858     * arg[2] = pointer to destination register rt
859     */
860     X(adde)
861     {
862     int old_ca = cpu->cd.ppc.xer & PPC_XER_CA;
863     uint64_t tmp = (uint32_t)reg(ic->arg[0]);
864     uint64_t tmp2 = tmp;
865     cpu->cd.ppc.xer &= PPC_XER_CA;
866     tmp += (uint32_t)reg(ic->arg[1]);
867     if (old_ca)
868     tmp ++;
869     if ((tmp >> 32) == (tmp2 >> 32))
870     cpu->cd.ppc.xer |= PPC_XER_CA;
871    
872     reg(ic->arg[2]) = (uint32_t)tmp;
873     }
874     X(addze)
875     {
876     int old_ca = cpu->cd.ppc.xer & PPC_XER_CA;
877     uint64_t tmp = (uint32_t)reg(ic->arg[0]);
878     uint64_t tmp2 = tmp;
879     cpu->cd.ppc.xer &= PPC_XER_CA;
880     if (old_ca)
881     tmp ++;
882     if ((tmp >> 32) == (tmp2 >> 32))
883     cpu->cd.ppc.xer |= PPC_XER_CA;
884     reg(ic->arg[2]) = (uint32_t)tmp;
885     }
886    
887    
888     /*
889     * subf: Subf, etc.
890     *
891     * arg[0] = pointer to source register ra
892     * arg[1] = pointer to source register rb
893     * arg[2] = pointer to destination register rt
894     */
895     X(subf) { reg(ic->arg[2]) = ~reg(ic->arg[0]) + reg(ic->arg[1]) + 1; }
896     X(subfe)
897     {
898     int old_ca = cpu->cd.ppc.xer & PPC_XER_CA;
899     uint64_t tmp = (uint32_t)(~reg(ic->arg[0]));
900     uint64_t tmp2 = tmp;
901    
902     cpu->cd.ppc.xer &= PPC_XER_CA;
903     tmp += (uint32_t)reg(ic->arg[1]);
904     if (old_ca)
905     tmp ++;
906     if ((tmp >> 32) == (tmp2 >> 32))
907     cpu->cd.ppc.xer |= PPC_XER_CA;
908     reg(ic->arg[2]) = (uint32_t)tmp;
909     }
910     X(subfze)
911     {
912     int old_ca = cpu->cd.ppc.xer & PPC_XER_CA;
913     uint64_t tmp = (uint32_t)(~reg(ic->arg[0]));
914     uint64_t tmp2 = tmp;
915     cpu->cd.ppc.xer &= PPC_XER_CA;
916     if (old_ca)
917     tmp ++;
918     if ((tmp >> 32) == (tmp2 >> 32))
919     cpu->cd.ppc.xer |= PPC_XER_CA;
920     reg(ic->arg[2]) = (uint32_t)tmp;
921     }
922    
923    
924     /*
925     * ori: OR immediate.
926     *
927     * arg[0] = pointer to source uint64_t
928     * arg[1] = immediate value (uint32_t or larger)
929     * arg[2] = pointer to destination uint64_t
930     */
931     X(ori)
932     {
933     reg(ic->arg[2]) = reg(ic->arg[0]) | (uint32_t)ic->arg[1];
934     }
935    
936    
937     /*
938     * user_syscall: Userland syscall.
939     *
940     * arg[0] = syscall "level" (usually 0)
941     */
942     X(user_syscall)
943     {
944     useremul_syscall(cpu, ic->arg[0]);
945     }
946    
947    
948     /*
949     * xori: XOR immediate.
950     *
951     * arg[0] = pointer to source uint64_t
952     * arg[1] = immediate value (uint32_t or larger)
953     * arg[2] = pointer to destination uint64_t
954     */
955     X(xori)
956     {
957     reg(ic->arg[2]) = reg(ic->arg[0]) ^ (uint32_t)ic->arg[1];
958     }
959    
960    
961     #include "tmp_ppc_loadstore.c"
962    
963    
964     /*****************************************************************************/
965    
966    
967     X(end_of_page)
968     {
969     /* Update the PC: (offset 0, but on the next page) */
970     cpu->pc &= ~((PPC_IC_ENTRIES_PER_PAGE-1) << 2);
971     cpu->pc += (PPC_IC_ENTRIES_PER_PAGE << 2);
972    
973     /* Find the new physical page and update the translation pointers: */
974     ppc_pc_to_pointers(cpu);
975    
976     /* end_of_page doesn't count as an executed instruction: */
977     cpu->n_translated_instrs --;
978     }
979    
980    
981     /*****************************************************************************/
982    
983    
984     /*
985     * ppc_combine_instructions():
986     *
987     * Combine two or more instructions, if possible, into a single function call.
988     */
989     void COMBINE_INSTRUCTIONS(struct cpu *cpu, struct ppc_instr_call *ic,
990     uint32_t addr)
991     {
992     int n_back;
993     n_back = (addr >> 2) & (PPC_IC_ENTRIES_PER_PAGE-1);
994    
995     if (n_back >= 1) {
996     /* TODO */
997     }
998    
999     /* TODO: Combine forward as well */
1000     }
1001    
1002    
1003     /*****************************************************************************/
1004    
1005    
1006     /*
1007     * ppc_instr_to_be_translated():
1008     *
1009     * Translate an instruction word into an ppc_instr_call. ic is filled in with
1010     * valid data for the translated instruction, or a "nothing" instruction if
1011     * there was a translation failure. The newly translated instruction is then
1012     * executed.
1013     */
1014     X(to_be_translated)
1015     {
1016     uint64_t addr, low_pc, tmp_addr;
1017     uint32_t iword;
1018     unsigned char *page;
1019     unsigned char ib[4];
1020     int main_opcode, rt, rs, ra, rb, rc, aa_bit, l_bit, lk_bit, spr, sh,
1021     xo, imm, load, size, update, zero, bf, bo, bi, bh, oe_bit, n64=0;
1022     void (*samepage_function)(struct cpu *, struct ppc_instr_call *);
1023     void (*rc_f)(struct cpu *, struct ppc_instr_call *);
1024    
1025     /* Figure out the (virtual) address of the instruction: */
1026     low_pc = ((size_t)ic - (size_t)cpu->cd.ppc.cur_ic_page)
1027     / sizeof(struct ppc_instr_call);
1028     addr = cpu->pc & ~((PPC_IC_ENTRIES_PER_PAGE-1)
1029     << PPC_INSTR_ALIGNMENT_SHIFT);
1030     addr += (low_pc << PPC_INSTR_ALIGNMENT_SHIFT);
1031     cpu->pc = addr;
1032     addr &= ~0x3;
1033    
1034     /* Read the instruction word from memory: */
1035     page = cpu->cd.ppc.host_load[addr >> 12];
1036    
1037     if (page != NULL) {
1038     /* fatal("TRANSLATION HIT!\n"); */
1039     memcpy(ib, page + (addr & 0xfff), sizeof(ib));
1040     } else {
1041     /* fatal("TRANSLATION MISS!\n"); */
1042     if (!cpu->memory_rw(cpu, cpu->mem, addr, ib,
1043     sizeof(ib), MEM_READ, CACHE_INSTRUCTION)) {
1044     fatal("to_be_translated(): "
1045     "read failed: TODO\n");
1046     goto bad;
1047     }
1048     }
1049    
1050     iword = *((uint32_t *)&ib[0]);
1051    
1052     #ifdef HOST_LITTLE_ENDIAN
1053     if (cpu->byte_order == EMUL_BIG_ENDIAN)
1054     #else
1055     if (cpu->byte_order == EMUL_LITTLE_ENDIAN)
1056     #endif
1057     iword = ((iword & 0xff) << 24) |
1058     ((iword & 0xff00) << 8) |
1059     ((iword & 0xff0000) >> 8) |
1060     ((iword & 0xff000000) >> 24);
1061    
1062    
1063     #define DYNTRANS_TO_BE_TRANSLATED_HEAD
1064     #include "cpu_dyntrans.c"
1065     #undef DYNTRANS_TO_BE_TRANSLATED_HEAD
1066    
1067    
1068     /*
1069     * Translate the instruction:
1070     */
1071    
1072     main_opcode = iword >> 26;
1073    
1074     switch (main_opcode) {
1075    
1076     case PPC_HI6_MULLI:
1077     rt = (iword >> 21) & 31;
1078     ra = (iword >> 16) & 31;
1079     imm = (int16_t)(iword & 0xffff);
1080     ic->f = instr(mulli);
1081     ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[ra]);
1082     ic->arg[1] = (ssize_t)imm;
1083     ic->arg[2] = (size_t)(&cpu->cd.ppc.gpr[rt]);
1084     break;
1085    
1086     case PPC_HI6_SUBFIC:
1087     rt = (iword >> 21) & 31;
1088     ra = (iword >> 16) & 31;
1089     imm = (int16_t)(iword & 0xffff);
1090     ic->f = instr(subfic);
1091     ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[ra]);
1092     ic->arg[1] = (ssize_t)imm;
1093     ic->arg[2] = (size_t)(&cpu->cd.ppc.gpr[rt]);
1094     break;
1095    
1096     case PPC_HI6_CMPLI:
1097     case PPC_HI6_CMPI:
1098     bf = (iword >> 23) & 7;
1099     l_bit = (iword >> 21) & 1;
1100     ra = (iword >> 16) & 31;
1101     if (main_opcode == PPC_HI6_CMPLI) {
1102     imm = iword & 0xffff;
1103     if (l_bit)
1104     ic->f = instr(cmpldi);
1105     else
1106     ic->f = instr(cmplwi);
1107     } else {
1108     imm = (int16_t)(iword & 0xffff);
1109     if (l_bit)
1110     ic->f = instr(cmpdi);
1111     else
1112     ic->f = instr(cmpwi);
1113     }
1114     ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[ra]);
1115     ic->arg[1] = (ssize_t)imm;
1116     ic->arg[2] = bf;
1117     break;
1118    
1119     case PPC_HI6_ADDIC:
1120     case PPC_HI6_ADDIC_DOT:
1121     if (cpu->cd.ppc.bits == 64) {
1122     fatal("addic for 64-bit: TODO\n");
1123     goto bad;
1124     }
1125     rt = (iword >> 21) & 31;
1126     ra = (iword >> 16) & 31;
1127     imm = (int16_t)(iword & 0xffff);
1128     if (main_opcode == PPC_HI6_ADDIC)
1129     ic->f = instr(addic);
1130     else
1131     ic->f = instr(addic_dot);
1132     ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[ra]);
1133     ic->arg[1] = (ssize_t)imm;
1134     ic->arg[2] = (size_t)(&cpu->cd.ppc.gpr[rt]);
1135     break;
1136    
1137     case PPC_HI6_ADDI:
1138     case PPC_HI6_ADDIS:
1139     rt = (iword >> 21) & 31; ra = (iword >> 16) & 31;
1140     ic->f = instr(addi);
1141     if (ra == 0)
1142     ic->arg[0] = (size_t)(&cpu->cd.ppc.zero);
1143     else
1144     ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[ra]);
1145     ic->arg[1] = (ssize_t)(int16_t)(iword & 0xffff);
1146     if (main_opcode == PPC_HI6_ADDIS)
1147     ic->arg[1] <<= 16;
1148     ic->arg[2] = (size_t)(&cpu->cd.ppc.gpr[rt]);
1149     break;
1150    
1151     case PPC_HI6_ANDI_DOT:
1152     case PPC_HI6_ANDIS_DOT:
1153     rs = (iword >> 21) & 31; ra = (iword >> 16) & 31;
1154     ic->f = instr(andi_dot);
1155     ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rs]);
1156     ic->arg[1] = iword & 0xffff;
1157     if (main_opcode == PPC_HI6_ANDIS_DOT)
1158     ic->arg[1] <<= 16;
1159     ic->arg[2] = (size_t)(&cpu->cd.ppc.gpr[ra]);
1160     break;
1161    
1162     case PPC_HI6_ORI:
1163     case PPC_HI6_ORIS:
1164     case PPC_HI6_XORI:
1165     case PPC_HI6_XORIS:
1166     rs = (iword >> 21) & 31; ra = (iword >> 16) & 31;
1167     if (main_opcode == PPC_HI6_ORI ||
1168     main_opcode == PPC_HI6_ORIS)
1169     ic->f = instr(ori);
1170     else
1171     ic->f = instr(xori);
1172     ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rs]);
1173     ic->arg[1] = iword & 0xffff;
1174     if (main_opcode == PPC_HI6_ORIS ||
1175     main_opcode == PPC_HI6_XORIS)
1176     ic->arg[1] <<= 16;
1177     ic->arg[2] = (size_t)(&cpu->cd.ppc.gpr[ra]);
1178     break;
1179    
1180     case PPC_HI6_LBZ:
1181     case PPC_HI6_LBZU:
1182     case PPC_HI6_LHZ:
1183     case PPC_HI6_LHZU:
1184     case PPC_HI6_LWZ:
1185     case PPC_HI6_LWZU:
1186     case PPC_HI6_STB:
1187     case PPC_HI6_STBU:
1188     case PPC_HI6_STH:
1189     case PPC_HI6_STHU:
1190     case PPC_HI6_STW:
1191     case PPC_HI6_STWU:
1192     rs = (iword >> 21) & 31;
1193     ra = (iword >> 16) & 31;
1194     imm = (int16_t)(iword & 0xffff);
1195     load = 0; zero = 1; size = 0; update = 0;
1196     switch (main_opcode) {
1197     case PPC_HI6_LBZ: load = 1; break;
1198     case PPC_HI6_LBZU: load = 1; update = 1; break;
1199     case PPC_HI6_LHZ: load = 1; size = 1; break;
1200     case PPC_HI6_LHZU: load = 1; size = 1; update = 1; break;
1201     case PPC_HI6_LWZ: load = 1; size = 2; break;
1202     case PPC_HI6_LWZU: load = 1; size = 2; update = 1; break;
1203     case PPC_HI6_STB: break;
1204     case PPC_HI6_STBU: update = 1; break;
1205     case PPC_HI6_STH: size = 1; break;
1206     case PPC_HI6_STHU: size = 1; update = 1; break;
1207     case PPC_HI6_STW: size = 2; break;
1208     case PPC_HI6_STWU: size = 2; update = 1; break;
1209     }
1210     ic->f =
1211     #ifdef MODE32
1212     ppc32_loadstore
1213     #else
1214     ppc_loadstore
1215     #endif
1216     [size + 4*zero + 8*load + (imm==0? 16 : 0) + 32*update];
1217    
1218     if (ra == 0 && update) {
1219     fatal("TODO: ra=0 && update?\n");
1220     goto bad;
1221     }
1222     ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rs]);
1223     if (ra == 0)
1224     ic->arg[1] = (size_t)(&cpu->cd.ppc.zero);
1225     else
1226     ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[ra]);
1227     ic->arg[2] = (ssize_t)imm;
1228     break;
1229    
1230     case PPC_HI6_BC:
1231     aa_bit = (iword >> 1) & 1;
1232     lk_bit = iword & 1;
1233     bo = (iword >> 21) & 31;
1234     bi = (iword >> 16) & 31;
1235     tmp_addr = (int64_t)(int16_t)(iword & 0xfffc);
1236     if (lk_bit) {
1237     fatal("lk_bit: NOT YET\n");
1238     goto bad;
1239     }
1240     if (aa_bit) {
1241     fatal("aa_bit: NOT YET\n");
1242     goto bad;
1243     }
1244     ic->f = instr(bc);
1245     samepage_function = instr(bc_samepage);
1246     ic->arg[0] = (ssize_t)tmp_addr;
1247     ic->arg[1] = bo;
1248     ic->arg[2] = bi;
1249     /* Branches are calculated as cur PC + offset. */
1250     /* Special case: branch within the same page: */
1251     {
1252     uint64_t mask_within_page =
1253     ((PPC_IC_ENTRIES_PER_PAGE-1) << 2) | 3;
1254     uint64_t old_pc = addr;
1255     uint64_t new_pc = old_pc + (int32_t)ic->arg[0];
1256     if ((old_pc & ~mask_within_page) ==
1257     (new_pc & ~mask_within_page)) {
1258     ic->f = samepage_function;
1259     ic->arg[0] = (size_t) (
1260     cpu->cd.ppc.cur_ic_page +
1261     ((new_pc & mask_within_page) >> 2));
1262     }
1263     }
1264     break;
1265    
1266     case PPC_HI6_SC:
1267     ic->arg[0] = (iword >> 5) & 0x7f;
1268     if (cpu->machine->userland_emul != NULL)
1269     ic->f = instr(user_syscall);
1270     else {
1271     fatal("PPC non-userland SYSCALL: TODO\n");
1272     goto bad;
1273     }
1274     break;
1275    
1276     case PPC_HI6_B:
1277     aa_bit = (iword & 2) >> 1;
1278     lk_bit = iword & 1;
1279     if (aa_bit) {
1280     fatal("aa_bit: NOT YET\n");
1281     goto bad;
1282     }
1283     tmp_addr = (int64_t)(int32_t)((iword & 0x03fffffc) << 6);
1284     tmp_addr = (int64_t)tmp_addr >> 6;
1285     if (lk_bit) {
1286     if (cpu->machine->show_trace_tree) {
1287     ic->f = instr(bl_trace);
1288     samepage_function = instr(bl_samepage_trace);
1289     } else {
1290     ic->f = instr(bl);
1291     samepage_function = instr(bl_samepage);
1292     }
1293     } else {
1294     ic->f = instr(b);
1295     samepage_function = instr(b_samepage);
1296     }
1297     ic->arg[0] = (ssize_t)tmp_addr;
1298     /* Branches are calculated as cur PC + offset. */
1299     /* Special case: branch within the same page: */
1300     {
1301     uint64_t mask_within_page =
1302     ((PPC_IC_ENTRIES_PER_PAGE-1) << 2) | 3;
1303     uint64_t old_pc = addr;
1304     uint64_t new_pc = old_pc + (int32_t)ic->arg[0];
1305     if ((old_pc & ~mask_within_page) ==
1306     (new_pc & ~mask_within_page)) {
1307     ic->f = samepage_function;
1308     ic->arg[0] = (size_t) (
1309     cpu->cd.ppc.cur_ic_page +
1310     ((new_pc & mask_within_page) >> 2));
1311     }
1312     }
1313     break;
1314    
1315     case PPC_HI6_19:
1316     xo = (iword >> 1) & 1023;
1317     switch (xo) {
1318    
1319     case PPC_19_BCLR:
1320     bo = (iword >> 21) & 31;
1321     bi = (iword >> 16) & 31;
1322     bh = (iword >> 11) & 3;
1323     lk_bit = iword & 1;
1324     if (lk_bit) {
1325     fatal("TODO: bclr with l_bit set\n");
1326     goto bad;
1327     }
1328     ic->f = instr(bclr);
1329     ic->arg[0] = bo;
1330     ic->arg[1] = bi;
1331     ic->arg[2] = bh;
1332     break;
1333    
1334     case PPC_19_ISYNC:
1335     /* TODO */
1336     ic->f = instr(nop);
1337     break;
1338    
1339     case PPC_19_CRXOR:
1340     ic->f = instr(crxor);
1341     ic->arg[0] = iword;
1342     break;
1343    
1344     default:goto bad;
1345     }
1346     break;
1347    
1348     case PPC_HI6_RLWINM:
1349     rs = (iword >> 21) & 31;
1350     ra = (iword >> 16) & 31;
1351     ic->f = instr(rlwinm);
1352     ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rs]);
1353     ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[ra]);
1354     ic->arg[2] = (uint32_t)iword;
1355     break;
1356    
1357     case PPC_HI6_31:
1358     xo = (iword >> 1) & 1023;
1359     switch (xo) {
1360    
1361     case PPC_31_CMPL:
1362     case PPC_31_CMP:
1363     bf = (iword >> 23) & 7;
1364     l_bit = (iword >> 21) & 1;
1365     ra = (iword >> 16) & 31;
1366     rb = (iword >> 11) & 31;
1367     if (xo == PPC_31_CMPL) {
1368     if (l_bit)
1369     ic->f = instr(cmpld);
1370     else
1371     ic->f = instr(cmplw);
1372     } else {
1373     if (l_bit)
1374     ic->f = instr(cmpd);
1375     else
1376     ic->f = instr(cmpw);
1377     }
1378     ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[ra]);
1379     ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[rb]);
1380     ic->arg[2] = bf;
1381     break;
1382    
1383     case PPC_31_MFSPR:
1384     rt = (iword >> 21) & 31;
1385     spr = ((iword >> 6) & 0x3e0) + ((iword >> 16) & 31);
1386     ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rt]);
1387     switch (spr) {
1388     case 8: ic->f = instr(mflr); break;
1389     case 272: ic->f = instr(mfsprg0); break;
1390     case 273: ic->f = instr(mfsprg1); break;
1391     case 274: ic->f = instr(mfsprg2); break;
1392     case 275: ic->f = instr(mfsprg3); break;
1393     default:fatal("UNIMPLEMENTED spr %i\n", spr);
1394     goto bad;
1395     }
1396     break;
1397    
1398     case PPC_31_MTSPR:
1399     rs = (iword >> 21) & 31;
1400     spr = ((iword >> 6) & 0x3e0) + ((iword >> 16) & 31);
1401     ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rs]);
1402     switch (spr) {
1403     case 8: ic->f = instr(mtlr); break;
1404     case 272: ic->f = instr(mtsprg0); break;
1405     case 273: ic->f = instr(mtsprg1); break;
1406     case 274: ic->f = instr(mtsprg2); break;
1407     case 275: ic->f = instr(mtsprg3); break;
1408     default:fatal("UNIMPLEMENTED spr %i\n", spr);
1409     goto bad;
1410     }
1411     break;
1412    
1413     case PPC_31_MFCR:
1414     rt = (iword >> 21) & 31;
1415     ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rt]);
1416     ic->f = instr(mfcr);
1417     break;
1418    
1419     case PPC_31_MFMSR:
1420     rt = (iword >> 21) & 31;
1421     ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rt]);
1422     ic->f = instr(mfmsr);
1423     break;
1424    
1425     case PPC_31_MTMSR:
1426     rs = (iword >> 21) & 31;
1427     l_bit = (iword >> 16) & 1;
1428     if (l_bit) {
1429     fatal("TODO: mtmsr l-bit\n");
1430     goto bad;
1431     }
1432     ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rs]);
1433     ic->f = instr(mtmsr);
1434     break;
1435    
1436     case PPC_31_MTCRF:
1437     rs = (iword >> 21) & 31;
1438     {
1439     int i, fxm = (iword >> 12) & 255;
1440     uint32_t tmp = 0;
1441     for (i=0; i<8; i++, fxm <<= 1) {
1442     tmp <<= 4;
1443     if (fxm & 128)
1444     tmp |= 0xf;
1445     }
1446     ic->arg[1] = (uint32_t)tmp;
1447     }
1448     ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rs]);
1449     ic->f = instr(mtcrf);
1450     break;
1451    
1452     case PPC_31_SRAWI:
1453     rs = (iword >> 21) & 31;
1454     ra = (iword >> 16) & 31;
1455     sh = (iword >> 11) & 31;
1456     rc = iword & 1;
1457     ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rs]);
1458     ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[ra]);
1459     ic->arg[2] = sh;
1460     if (rc)
1461     ic->f = instr(srawi_dot);
1462     else
1463     ic->f = instr(srawi);
1464     break;
1465    
1466     case PPC_31_SYNC:
1467     case PPC_31_EIEIO:
1468     /* TODO */
1469     ic->f = instr(nop);
1470     break;
1471    
1472     case PPC_31_NEG:
1473     rt = (iword >> 21) & 31;
1474     ra = (iword >> 16) & 31;
1475     rc = iword & 1;
1476     ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[ra]);
1477     ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[rt]);
1478     if (rc)
1479     ic->f = instr(neg_dot);
1480     else
1481     ic->f = instr(neg);
1482     break;
1483    
1484     case PPC_31_LBZX:
1485     case PPC_31_LBZUX:
1486     case PPC_31_LHZX:
1487     case PPC_31_LHZUX:
1488     case PPC_31_LWZX:
1489     case PPC_31_LWZUX:
1490     case PPC_31_STBX:
1491     case PPC_31_STBUX:
1492     case PPC_31_STHX:
1493     case PPC_31_STHUX:
1494     case PPC_31_STWX:
1495     case PPC_31_STWUX:
1496     case PPC_31_STDX:
1497     case PPC_31_STDUX:
1498     rs = (iword >> 21) & 31;
1499     ra = (iword >> 16) & 31;
1500     rb = (iword >> 11) & 31;
1501     ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rs]);
1502     if (ra == 0)
1503     ic->arg[1] = (size_t)(&cpu->cd.ppc.zero);
1504     else
1505     ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[ra]);
1506     ic->arg[2] = (size_t)(&cpu->cd.ppc.gpr[rb]);
1507     load = 0; zero = 1; size = 0; update = 0;
1508     switch (xo) {
1509     case PPC_31_LBZX: load = 1; break;
1510     case PPC_31_LBZUX: load = update = 1; break;
1511     case PPC_31_LHZX: size = 1; load = 1; break;
1512     case PPC_31_LHZUX: size = 1; load = update = 1; break;
1513     case PPC_31_LWZX: size = 2; load = 1; break;
1514     case PPC_31_LWZUX: size = 2; load = update = 1; break;
1515     case PPC_31_STBX: break;
1516     case PPC_31_STBUX: update = 1; break;
1517     case PPC_31_STHX: size = 1; break;
1518     case PPC_31_STHUX: size = 1; update = 1; break;
1519     case PPC_31_STWX: size = 2; break;
1520     case PPC_31_STWUX: size = 2; update = 1; break;
1521     case PPC_31_STDX: size = 3; break;
1522     case PPC_31_STDUX: size = 3; update = 1; break;
1523     }
1524     ic->f =
1525     #ifdef MODE32
1526     ppc32_loadstore_indexed
1527     #else
1528     ppc_loadstore_indexed
1529     #endif
1530     [size + 4*zero + 8*load + 16*update];
1531     if (ra == 0 && update) {
1532     fatal("TODO: ra=0 && update?\n");
1533     goto bad;
1534     }
1535     break;
1536    
1537     case PPC_31_SLW:
1538     case PPC_31_SRAW:
1539     case PPC_31_AND:
1540     case PPC_31_ANDC:
1541     case PPC_31_NOR:
1542     case PPC_31_OR:
1543     case PPC_31_ORC:
1544     case PPC_31_XOR:
1545     rs = (iword >> 21) & 31;
1546     ra = (iword >> 16) & 31;
1547     rb = (iword >> 11) & 31;
1548     rc = iword & 1;
1549     rc_f = NULL;
1550     switch (xo) {
1551     case PPC_31_SLW: ic->f = instr(slw);
1552     rc_f = instr(slw_dot); break;
1553     case PPC_31_SRAW: ic->f = instr(sraw);
1554     rc_f = instr(sraw_dot); break;
1555     case PPC_31_AND: ic->f = instr(and);
1556     rc_f = instr(and_dot); break;
1557     case PPC_31_ANDC: ic->f = instr(andc);
1558     rc_f = instr(andc_dot); break;
1559     case PPC_31_NOR: ic->f = instr(nor);
1560     rc_f = instr(nor_dot); break;
1561     case PPC_31_OR: ic->f = instr(or);
1562     rc_f = instr(or_dot); break;
1563     case PPC_31_ORC: ic->f = instr(orc);
1564     rc_f = instr(orc_dot); break;
1565     case PPC_31_XOR: ic->f = instr(xor);
1566     rc_f = instr(xor_dot); break;
1567     }
1568     ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[rs]);
1569     ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[rb]);
1570     ic->arg[2] = (size_t)(&cpu->cd.ppc.gpr[ra]);
1571     if (rc)
1572     ic->f = rc_f;
1573     break;
1574    
1575     case PPC_31_MULLW:
1576     case PPC_31_MULHW:
1577     case PPC_31_MULHWU:
1578     case PPC_31_DIVW:
1579     case PPC_31_DIVWU:
1580     case PPC_31_ADD:
1581     case PPC_31_ADDC:
1582     case PPC_31_ADDE:
1583     case PPC_31_ADDZE:
1584     case PPC_31_SUBF:
1585     case PPC_31_SUBFE:
1586     case PPC_31_SUBFZE:
1587     rt = (iword >> 21) & 31;
1588     ra = (iword >> 16) & 31;
1589     rb = (iword >> 11) & 31;
1590     oe_bit = (iword >> 10) & 1;
1591     rc = iword & 1;
1592     if (rc) {
1593     fatal("RC bit not yet implemented\n");
1594     goto bad;
1595     }
1596     if (oe_bit) {
1597     fatal("oe_bit not yet implemented\n");
1598     goto bad;
1599     }
1600     switch (xo) {
1601     case PPC_31_MULLW: ic->f = instr(mullw); break;
1602     case PPC_31_MULHW: ic->f = instr(mulhw); break;
1603     case PPC_31_MULHWU: ic->f = instr(mulhwu); break;
1604     case PPC_31_DIVW: ic->f = instr(divw); n64=1; break;
1605     case PPC_31_DIVWU: ic->f = instr(divwu); n64=1; break;
1606     case PPC_31_ADD: ic->f = instr(add); break;
1607     case PPC_31_ADDC: ic->f = instr(addc); n64=1; break;
1608     case PPC_31_ADDE: ic->f = instr(adde); n64=1; break;
1609     case PPC_31_ADDZE: ic->f = instr(addze); n64=1; break;
1610     case PPC_31_SUBF: ic->f = instr(subf); break;
1611     case PPC_31_SUBFE: ic->f = instr(subfe); n64=1; break;
1612     case PPC_31_SUBFZE: ic->f = instr(subfze); n64=1;break;
1613     }
1614     ic->arg[0] = (size_t)(&cpu->cd.ppc.gpr[ra]);
1615     ic->arg[1] = (size_t)(&cpu->cd.ppc.gpr[rb]);
1616     ic->arg[2] = (size_t)(&cpu->cd.ppc.gpr[rt]);
1617     if (cpu->cd.ppc.bits == 64 && n64) {
1618     fatal("Not yet for 64-bit mode\n");
1619     goto bad;
1620     }
1621     break;
1622    
1623     default:goto bad;
1624     }
1625     break;
1626    
1627     default:goto bad;
1628     }
1629    
1630    
1631     #define DYNTRANS_TO_BE_TRANSLATED_TAIL
1632     #include "cpu_dyntrans.c"
1633     #undef DYNTRANS_TO_BE_TRANSLATED_TAIL
1634     }
1635    

  ViewVC Help
Powered by ViewVC 1.1.26