1 /*
2 ===========================================================================
3 Copyright (C) 2008 Przemyslaw Iskra <sparky@pld-linux.org>
4 
5 This file is part of Quake III Arena source code.
6 
7 Quake III Arena source code is free software; you can redistribute it
8 and/or modify it under the terms of the GNU General Public License as
9 published by the Free Software Foundation; either version 2 of the License,
10 or (at your option) any later version.
11 
12 Quake III Arena source code is distributed in the hope that it will be
13 useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16 
17 You should have received a copy of the GNU General Public License
18 along with Quake III Arena source code; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
20 ===========================================================================
21 */
22 
23 #ifndef VM_POWERPC_ASM_H
24 #define VM_POWERPC_ASM_H
25 
26 /*
27  * Register information according to:
28  * http://refspecs.freestandards.org/elf/elfspec_ppc.pdf
29  */
30 
31 #define r0	0	// volatile
32 #define r1	1	// caller safe ( stack pointer )
33 #define r2	2	// reserved
34 #define r3	3	// callee safe
35 #define r4	4	// callee safe
36 #define r5	5	// callee safe
37 #define r6	6	// callee safe
38 #define r7	7	// callee safe
39 #define r8	8	// callee safe
40 #define r9	9	// callee safe
41 #define r10	10	// callee safe
42 #define r11	11	// volatile
43 #define r12	12	// volatile
44 #define r13	13	// reserved ( small data area )
45 #define r14	14	// caller safe
46 #define r15	15	// caller safe
47 #define r16	16	// caller safe
48 #define r17	17	// caller safe
49 #define r18	18	// caller safe
50 #define r19	19	// caller safe
51 #define r20	20	// caller safe
52 #define r21	21	// caller safe
53 #define r22	22	// caller safe
54 #define r23	23	// caller safe
55 #define r24	24	// caller safe
56 #define r25	25	// caller safe
57 #define r26	26	// caller safe
58 #define r27	27	// caller safe
59 #define r28	28	// caller safe
60 #define r29	29	// caller safe
61 #define r30	30	// caller safe
62 #define r31	31	// caller safe ( environment pointers )
63 
64 #define f0	0	// callee safe
65 #define f1	1	// callee safe
66 #define f2	2	// callee safe
67 #define f3	3	// callee safe
68 #define f4	4	// callee safe
69 #define f5	5	// callee safe
70 #define f6	6	// callee safe
71 #define f7	7	// callee safe
72 #define f8	8	// callee safe
73 #define f9	9	// callee safe
74 #define f10	10	// callee safe
75 #define f11	11	// callee safe
76 #define f12	12	// callee safe
77 #define f13	13	// callee safe
78 #define f14	14	// caller safe
79 #define f15	15	// caller safe
80 #define f16	16	// caller safe
81 #define f17	17	// caller safe
82 #define f18	18	// caller safe
83 #define f19	19	// caller safe
84 #define f20	20	// caller safe
85 #define f21	21	// caller safe
86 #define f22	22	// caller safe
87 #define f23	23	// caller safe
88 #define f24	24	// caller safe
89 #define f25	25	// caller safe
90 #define f26	26	// caller safe
91 #define f27	27	// caller safe
92 #define f28	28	// caller safe
93 #define f29	29	// caller safe
94 #define f30	30	// caller safe
95 #define f31	31	// caller safe
96 
97 #define cr0	0	// volatile
98 #define cr1	1	// volatile
99 #define cr2	2	// caller safe
100 #define cr3	3	// caller safe
101 #define cr4	4	// caller safe
102 #define cr5	5	// volatile
103 #define cr6	6	// volatile
104 #define cr7	7	// volatile
105 
106 #define lt	0
107 #define gt	1
108 #define eq	2
109 #define so	3
110 
111 // branch bo field values
112 #define branchLikely	1
113 #define branchFalse	4
114 #define branchTrue	12
115 #define branchAlways	20
116 
117 // branch extensions (change branch type)
118 #define branchExtLink	0x0001
119 
120 
121 /*
122  * This list must match exactly the powerpc_opcodes list from vm_powerpc_asm.c
123  * If you're changing the original list remember to regenerate this one. You
124  * may do so using this perl script:
125    perl -p -e 'BEGIN{%t=("-"=>m=>"+"=>p=>"."=>d=>);$l=""}$o=0 if/^}/;
126 	if($o && s/^{ "(.*?)([\.+-])?".+/i\U$1\E$t{$2}/s){$_.="_" while$l{$_};
127 	$l{$_}=1;if(length $l.$_ > 70){$s=$_;$_="\t$l\n";$l="$s,"}else
128 	{$l.=" $_,";$_=undef}}else{$o=1 if/powerpc_opcodes.*=/;$_=undef};
129 	END{print "\t$l\n"}' < vm_powerpc_asm.c
130  */
131 
132 typedef enum powerpc_iname {
133 	iCMPLWI, iCMPWI, iCMPW, iCMPLW, iFCMPU, iLI, iLIS, iADDI, iADDIS,
134 	iBLTm, iBC, iBCL, iB, iBL, iBLR, iBCTR, iBCTRL, iRLWINM, iNOP, iORI,
135 	iXORIS, iLDX, iLWZX, iSLW, iAND, iSUB, iLBZX, iNEG, iNOT, iSTWX, iSTBX,
136 	iMULLW, iADD, iLHZX, iXOR, iMFLR, iSTHX, iMR, iOR, iDIVWU, iMTLR,
137 	iMTCTR, iDIVW, iLFSX, iSRW, iSTFSX, iSRAW, iEXTSH, iEXTSB, iLWZ, iLBZ,
138 	iSTW, iSTWU, iSTB, iLHZ, iSTH, iLFS, iLFD, iSTFS, iSTFD, iLD, iFDIVS,
139 	iFSUBS, iFADDS, iFMULS, iSTD, iSTDU, iFRSP, iFCTIWZ, iFSUB, iFNEG,
140 } powerpc_iname_t;
141 
142 #include <stdint.h>
143 
144 typedef uint32_t ppc_instruction_t;
145 
146 extern ppc_instruction_t
147 asm_instruction( powerpc_iname_t, const int, const long int * );
148 
149 #define IN( inst, args... ) \
150 ({\
151 	const long int argv[] = { args };\
152 	const int argc = sizeof( argv ) / sizeof( argv[0] ); \
153 	asm_instruction( inst, argc, argv );\
154 })
155 
156 #endif
157