Add ABFD argument to sim_open call. Pass through to sim_config so
[deliverable/binutils-gdb.git] / sim / sh / gencode.c
1 /* Simulator/Opcode generator for the Hitachi Super-H architecture.
2
3 Written by Steve Chamberlain of Cygnus Support.
4 sac@cygnus.com
5
6 This file is part of SH sim
7
8
9 THIS SOFTWARE IS NOT COPYRIGHTED
10
11 Cygnus offers the following for use in the public domain. Cygnus
12 makes no warranty with regard to the software or it's performance
13 and the user accepts the software "AS IS" with all faults.
14
15 CYGNUS DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD TO
16 THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
18
19 */
20
21 /* This program generates the opcode table for the assembler and
22 the simulator code
23
24 -t prints a pretty table for the assembler manual
25 -s generates the simulator code jump table
26 -d generates a define table
27 -x generates the simulator code switch statement
28 default generates the opcode tables
29
30 */
31
32 #include <stdio.h>
33
34 typedef struct
35 {
36 char *defs;
37 char *refs;
38 char *name;
39 char *code;
40 char *stuff[10];
41 int index;
42 }
43
44 op;
45
46
47 op tab[] =
48 {
49
50 {"n","","add #<imm>,<REG_N>", "0111nnnni8*1....", "R[n] += SEXT(i);if (i == 0) { UNDEF(n); break; } "},
51 {"n","mn","add <REG_M>,<REG_N>", "0011nnnnmmmm1100", "R[n] += R[m];"},
52 {"n","mn","addc <REG_M>,<REG_N>", "0011nnnnmmmm1110",
53 "ult=R[n]+T;T=ult<R[n];R[n]=ult+R[m];T|=R[n]<ult;"},
54 {"n","mn","addv <REG_M>,<REG_N>", "0011nnnnmmmm1111",
55 "ult = R[n] + R[m]; T = ((~(R[n] ^ R[m]) & (ult ^ R[n])) >> 31); R[n] = ult;"},
56 {"0","","and #<imm>,R0", "11001001i8*1....", ";R0&=i;"},
57 {"n","nm","and <REG_M>,<REG_N>", "0010nnnnmmmm1001", " R[n]&=R[m];"},
58 {"","0","and.b #<imm>,@(R0,GBR)", "11001101i8*1....", ";WBAT(GBR+R0, RBAT(GBR+R0) & i);"},
59
60 {"","","bra <bdisp12>", "1010i12.........", "ult = PC; PC=PC+(i<<1)+2;SL(ult+2);"},
61 {"","","bsr <bdisp12>", "1011i12.........", "PR = PC + 4; PC=PC+(i<<1)+2;SL(PR-2);"},
62 {"","","bt <bdisp8>", "10001001i8p1....", "if(T) {PC+=(SEXT(i)<<1)+2;C+=2;}"},
63 {"","","bf <bdisp8>", "10001011i8p1....", "if(T==0) {PC+=(SEXT(i)<<1)+2;C+=2;}"},
64 {"","","bt.s <bdisp8>", "10001101i8p1....","if(T) {ult = PC; PC+=(SEXT(i)<<1)+2;C+=2;SL(ult+2);}"},
65 {"","","bf.s <bdisp8>", "10001111i8p1....","if(!T) {ult = PC; PC+=(SEXT(i)<<1)+2;C+=2;SL(ult+2);}"},
66 {"","","clrmac", "0000000000101000", "MACH = MACL = 0;"},
67 {"","","clrs", "0000000001001000", "S= 0;"},
68 {"","","clrt", "0000000000001000", "T= 0;"},
69 {"","0","cmp/eq #<imm>,R0", "10001000i8*1....", ";T = R0 == SEXT(i);"},
70 {"","mn","cmp/eq <REG_M>,<REG_N>", "0011nnnnmmmm0000", "T=R[n]==R[m];"},
71 {"","mn","cmp/ge <REG_M>,<REG_N>", "0011nnnnmmmm0011", "T=R[n]>=R[m];"},
72 {"","mn","cmp/gt <REG_M>,<REG_N>", "0011nnnnmmmm0111", "T=R[n]>R[m];"},
73 {"","mn","cmp/hi <REG_M>,<REG_N>", "0011nnnnmmmm0110", "T=UR[n]>UR[m];"},
74 {"","mn","cmp/hs <REG_M>,<REG_N>", "0011nnnnmmmm0010", "T=UR[n]>=UR[m];"},
75 {"","n","cmp/pl <REG_N>", "0100nnnn00010101", "T = R[n]>0;"},
76 {"","n","cmp/pz <REG_N>", "0100nnnn00010001", "T = R[n]>=0;"},
77 {"","mn","cmp/str <REG_M>,<REG_N>", "0010nnnnmmmm1100",
78 "ult = R[n] ^ R[m]; T=((ult&0xff000000)==0) |((ult&0xff0000)==0) |((ult&0xff00)==0) |((ult&0xff)==0); "},
79 {"","mn","div0s <REG_M>,<REG_N>", "0010nnnnmmmm0111", "Q=(R[n]&sbit)!=0; M=(R[m]&sbit)!=0; T=M!=Q;;"},
80 {"","","div0u", "0000000000011001", "M=Q=T=0;"},
81 {"","","div1 <REG_M>,<REG_N>", "0011nnnnmmmm0100", "T=div1(R,m,n,T);"},
82 {"n","m","exts.b <REG_M>,<REG_N>", "0110nnnnmmmm1110", "R[n] = SEXT(R[m]);"},
83 {"n","m","exts.w <REG_M>,<REG_N>", "0110nnnnmmmm1111", "R[n] = SEXTW(R[m]);"},
84 {"n","m","extu.b <REG_M>,<REG_N>", "0110nnnnmmmm1100", "R[n] = R[m] & 0xff;"},
85 {"n","m","extu.w <REG_M>,<REG_N>", "0110nnnnmmmm1101", "R[n] = R[m] & 0xffff;"},
86 {"","n","jmp @<REG_N>", "0100nnnn00101011", "ult = PC; PC=R[n]-2; SL(ult+2);"},
87 {"","n","jsr @<REG_N>", "0100nnnn00001011", "PR = PC + 4; PC=R[n]-2; if (~doprofile) gotcall(PR,PC+2);SL(PR-2);"},
88 {"","n","ldc <REG_N>,SR", "0100nnnn00001110", "SET_SR(R[n]);"},
89 {"","n","ldc <REG_N>,GBR", "0100nnnn00011110", "GBR=R[n];"},
90 {"","n","ldc <REG_N>,VBR", "0100nnnn00101110", "VBR=R[n];"},
91 {"","n","ldc <REG_N>,SSR", "0100nnnn00111110", "SSR=R[n];"},
92 {"","n","ldc <REG_N>,SPC", "0100nnnn01001110", "SPC=R[n];"},
93 {"","n","ldc.l @<REG_N>+,SR", "0100nnnn00000111", "SET_SR(RLAT(R[n]));R[n]+=4;;"},
94 {"","n","ldc.l @<REG_N>+,GBR", "0100nnnn00010111", "GBR=RLAT(R[n]);R[n]+=4;;"},
95 {"","n","ldc.l @<REG_N>+,VBR", "0100nnnn00100111", "VBR=RLAT(R[n]);R[n]+=4;;"},
96 {"","n","ldc.l @<REG_N>+,SSR", "0100nnnn00110111", "SSR=RLAT(R[n]);R[n]+=4;;"},
97 {"","n","ldc.l @<REG_N>+,SPC", "0100nnnn01000111", "SPC=RLAT(R[n]);R[n]+=4;;"},
98 {"","n","lds <REG_N>,MACH", "0100nnnn00001010", "MACH = R[n];"},
99 {"","n","lds <REG_N>,MACL", "0100nnnn00011010", "MACL= R[n];"},
100 {"","n","lds <REG_N>,PR", "0100nnnn00101010", "PR = R[n];"},
101 {"","n","lds.l @<REG_N>+,MACH", "0100nnnn00000110", "MACH = SEXT(RLAT(R[n]));R[n]+=4;"},
102 {"","n","lds.l @<REG_N>+,MACL", "0100nnnn00010110", "MACL = RLAT(R[n]);R[n]+=4;"},
103 {"","n","lds.l @<REG_N>+,PR", "0100nnnn00100110", "PR = RLAT(R[n]);R[n]+=4;;"},
104 {"","","ldtlb", "0000000000111000", "/*XXX*/ abort();"},
105 {"","n","mac.w @<REG_M>+,@<REG_N>+", "0100nnnnmmmm1111", "macw(R0,memory,n,m);"},
106 {"n","","mov #<imm>,<REG_N>", "1110nnnni8*1....", "R[n] = SEXT(i);"},
107 {"n","m","mov <REG_M>,<REG_N>", "0110nnnnmmmm0011", "R[n] = R[m];"},
108 {"","mn0","mov.b <REG_M>,@(R0,<REG_N>)", "0000nnnnmmmm0100", "WBAT(R[n]+R0, R[m]);"},
109 {"","nm","mov.b <REG_M>,@-<REG_N>", "0010nnnnmmmm0100", "R[n]--; WBAT(R[n],R[m]);"},
110 {"","mn","mov.b <REG_M>,@<REG_N>", "0010nnnnmmmm0000", "WBAT(R[n], R[m]);"},
111 {"0","m","mov.b @(<disp>,<REG_M>),R0", "10000100mmmmi4*1", "R0=RSBAT(i+R[m]);L(0);"},
112 {"0","","mov.b @(<disp>,GBR),R0", "11000100i8*1....", "R0=RSBAT(i+GBR);L(0);"},
113 {"n","0m","mov.b @(R0,<REG_M>),<REG_N>", "0000nnnnmmmm1100", "R[n]=RSBAT(R0+R[m]);L(n);"},
114 {"n","m","mov.b @<REG_M>+,<REG_N>", "0110nnnnmmmm0100", "R[n] = RSBAT(R[m]);L(n);R[m]++;"},
115 {"n","m","mov.b @<REG_M>,<REG_N>", "0110nnnnmmmm0000", "R[n]=RSBAT(R[m]);L(n);"},
116 {"","m0","mov.b R0,@(<disp>,<REG_M>)", "10000000mmmmi4*1", "WBAT(i+R[m],R0);"},
117 {"","0","mov.b R0,@(<disp>,GBR)", "11000000i8*1....", "WBAT(i+GBR,R0);"},
118 {"","nm","mov.l <REG_M>,@(<disp>,<REG_N>)", "0001nnnnmmmmi4*4", "WLAT(i+R[n],R[m]);"},
119 {"","nm0","mov.l <REG_M>,@(R0,<REG_N>)", "0000nnnnmmmm0110", "WLAT(R0+R[n],R[m]);"},
120 {"","nm","mov.l <REG_M>,@-<REG_N>", "0010nnnnmmmm0110", "R[n]-=4;WLAT(R[n],R[m]);"},
121 {"","nm","mov.l <REG_M>,@<REG_N>", "0010nnnnmmmm0010", "WLAT(R[n], R[m]);"},
122 {"n","m","mov.l @(<disp>,<REG_M>),<REG_N>","0101nnnnmmmmi4*4", "R[n]=RLAT(i+R[m]);L(n);"},
123 {"0","","mov.l @(<disp>,GBR),R0", "11000110i8*4....", "R0=RLAT(i+GBR);L(0);"},
124 {"n","","mov.l @(<disp>,PC),<REG_N>", "1101nnnni8p4....", "R[n]=RLAT((i+4+PC) & ~3);L(n);"},
125 {"n","m","mov.l @(R0,<REG_M>),<REG_N>", "0000nnnnmmmm1110", "R[n]=RLAT(R0+R[m]);L(n);"},
126 {"nm","m","mov.l @<REG_M>+,<REG_N>", "0110nnnnmmmm0110", "R[n]=RLAT(R[m]);R[m]+=4;L(n);"},
127 {"n","m","mov.l @<REG_M>,<REG_N>", "0110nnnnmmmm0010", "R[n]=RLAT(R[m]);L(n);"},
128 {"","0","mov.l R0,@(<disp>,GBR)", "11000010i8*4....", "WLAT(i+GBR,R0);"},
129 {"","m0n","mov.w <REG_M>,@(R0,<REG_N>)", "0000nnnnmmmm0101", "WWAT(R0+R[n],R[m]);"},
130 {"n","mn","mov.w <REG_M>,@-<REG_N>", "0010nnnnmmmm0101", "R[n]-=2;WWAT(R[n],R[m]);"},
131 {"","nm","mov.w <REG_M>,@<REG_N>", "0010nnnnmmmm0001", "WWAT(R[n],R[m]);"},
132 {"0","m","mov.w @(<disp>,<REG_M>),R0", "10000101mmmmi4*2", "R0=RSWAT(i+R[m]);L(0);"},
133 {"0","","mov.w @(<disp>,GBR),R0", "11000101i8*2....", "R0=RSWAT(i+GBR);L(0);"},
134 {"n","","mov.w @(<disp>,PC),<REG_N>", "1001nnnni8p2....", "R[n]=RSWAT(PC+i+4);L(n);"},
135 {"n","m0","mov.w @(R0,<REG_M>),<REG_N>", "0000nnnnmmmm1101", "R[n]=RSWAT(R0+R[m]);L(n);"},
136 {"nm","n","mov.w @<REG_M>+,<REG_N>", "0110nnnnmmmm0101", "R[n]=RSWAT(R[m]);R[m]+=2;L(n);"},
137 {"n","m","mov.w @<REG_M>,<REG_N>", "0110nnnnmmmm0001", "R[n]=RSWAT(R[m]);L(n);"},
138 {"","0m","mov.w R0,@(<disp>,<REG_M>)", "10000001mmmmi4*2", "WWAT(i+R[m],R0);"},
139 {"","0","mov.w R0,@(<disp>,GBR)", "11000001i8*2....", "WWAT(i+GBR,R0);"},
140 {"0","","mova @(<disp>,PC),R0", "11000111i8p4....", "R0=((i+4+PC) & ~0x3);"},
141 {"n","","movt <REG_N>", "0000nnnn00101001", "R[n]=T;"},
142 {"","mn","muls <REG_M>,<REG_N>", "0010nnnnmmmm1111","MACL=((int)(short)R[n])*((int)(short)R[m]);"},
143 {"","mn","mul.l <REG_M>,<REG_N>","0000nnnnmmmm0111","MACL=((int)R[n])*((int)R[m]);"},
144 {"","mn","mulu <REG_M>,<REG_N>", "0010nnnnmmmm1110","MACL=((unsigned int)(unsigned short)R[n])*((unsigned int)(unsigned short)R[m]);"},
145 {"n","m","neg <REG_M>,<REG_N>", "0110nnnnmmmm1011", "R[n] = - R[m];"},
146 {"n","m","negc <REG_M>,<REG_N>", "0110nnnnmmmm1010", "ult=-T;T=ult>0;R[n]=ult-R[m];T|=R[n]>ult;"},
147 {"","","nop", "0000000000001001", ""},
148 {"n","m","not <REG_M>,<REG_N>", "0110nnnnmmmm0111", "R[n]=~R[m];"},
149 {"0","","or #<imm>,R0", "11001011i8*1....", "R0|=i;"},
150 {"n","m","or <REG_M>,<REG_N>", "0010nnnnmmmm1011", "R[n]|=R[m];"},
151 {"","0","or.b #<imm>,@(R0,GBR)", "11001111i8*1....", "WBAT(R0+GBR,RBAT(R0+GBR)|i);"},
152 {"n","n","rotcl <REG_N>", "0100nnnn00100100", "ult=R[n]<0;R[n]=(R[n]<<1)|T;T=ult;"},
153 {"n","n","rotcr <REG_N>", "0100nnnn00100101", "ult=R[n]&1;R[n]=(UR[n]>>1)|(T<<31);T=ult;"},
154 {"n","n","rotl <REG_N>", "0100nnnn00000100", "T=R[n]<0;R[n]<<=1;R[n]|=T;"},
155 {"n","n","rotr <REG_N>", "0100nnnn00000101", "T=R[n]&1;R[n] = UR[n]>> 1;R[n]|=(T<<31);"},
156 {"","","rte", "0000000000101011",
157 "{ int tmp = PC; PC=RLAT(R[15])+2;R[15]+=4;SET_SR(RLAT(R[15]) & 0x3f3);R[15]+=4;SL(tmp+2);}"},
158 {"","","rts", "0000000000001011", "ult=PC;PC=PR-2;SL(ult+2);"},
159 {"","","sets", "0000000001011000", "S=1;"},
160 {"","","sett", "0000000000011000", "T=1;"},
161 {"n","mn","shad <REG_M>,<REG_N>", "0100nnnnmmmm1100",
162 "R[n] = (R[m] < 0) ? (R[n] >> ((-R[m])&0x1f)) : (R[n] << (R[m] & 0x1f));"},
163 {"n","mn","shld <REG_M>,<REG_N>", "0100nnnnmmmm1101",
164 "R[n] = (R[m] < 0) ? (UR[n] >> ((-R[m])&0x1f)): (R[n] << (R[m] & 0x1f));"},
165 {"n","n","shal <REG_N>", "0100nnnn00100000", "T=R[n]<0; R[n]<<=1;"},
166 {"n","n","shar <REG_N>", "0100nnnn00100001", "T=R[n]&1; R[n] = R[n] >> 1;"},
167 {"n","n","shll <REG_N>", "0100nnnn00000000", "T=R[n]<0; R[n]<<=1;"},
168 {"n","n","shll16 <REG_N>", "0100nnnn00101000", "R[n]<<=16;"},
169 {"n","n","shll2 <REG_N>", "0100nnnn00001000", "R[n]<<=2;"},
170 {"n","n","shll8 <REG_N>", "0100nnnn00011000", "R[n]<<=8;"},
171 {"n","n","shlr <REG_N>", "0100nnnn00000001", "T=R[n]&1;R[n]=UR[n]>>1;"},
172 {"n","n","shlr16 <REG_N>", "0100nnnn00101001", "R[n]=UR[n]>>16;"},
173 {"n","n","shlr2 <REG_N>", "0100nnnn00001001", "R[n]=UR[n]>>2;"},
174 {"n","n","shlr8 <REG_N>", "0100nnnn00011001", "R[n]=UR[n]>>8;"},
175 {"","","sleep", "0000000000011011", "trap(0xc3,R0,memory,maskl,maskw,little_endian);PC-=2;"},
176 {"n","","stc SR,<REG_N>", "0000nnnn00000010", "R[n]=GET_SR();"},
177 {"n","","stc GBR,<REG_N>", "0000nnnn00010010", "R[n]=GBR;"},
178 {"n","","stc VBR,<REG_N>", "0000nnnn00100010", "R[n]=VBR;"},
179 {"n","","stc SSR,<REG_N>", "0000nnnn00110010", "R[n]=SSR;"},
180 {"n","","stc SPC,<REG_N>", "0000nnnn01000010", "R[n]=SPC;"},
181 {"n","n","stc.l SR,@-<REG_N>", "0100nnnn00000011", "R[n]-=4;WLAT(R[n],GET_SR());"},
182 {"n","n","stc.l GBR,@-<REG_N>", "0100nnnn00010011", "R[n]-=4;WLAT(R[n],GBR);;"},
183 {"n","n","stc.l VBR,@-<REG_N>", "0100nnnn00100011", "R[n]-=4;WLAT(R[n],VBR);"},
184 {"n","n","stc.l SSR,@-<REG_N>", "0100nnnn00110011", "R[n]-=4;WLAT(R[n],SSR);"},
185 {"n","n","stc.l SPC,@-<REG_N>", "0100nnnn01000011", "R[n]-=4;WLAT(R[n],SPC);"},
186 {"n","","sts MACH,<REG_N>", "0000nnnn00001010", "R[n]=MACH;"},
187 {"n","","sts MACL,<REG_N>", "0000nnnn00011010", "R[n]=MACL;"},
188 {"n","","sts PR,<REG_N>", "0000nnnn00101010", "R[n]=PR;"},
189 {"n","n","sts.l MACH,@-<REG_N>", "0100nnnn00000010", "R[n]-=4;WLAT(R[n],MACH);"},
190 {"n","n","sts.l MACL,@-<REG_N>", "0100nnnn00010010", "R[n]-=4;WLAT(R[n],MACL);"},
191 {"n","n","sts.l PR,@-<REG_N>", "0100nnnn00100010", "R[n]-=4;WLAT(R[n],PR);"},
192 {"n","nm","sub <REG_M>,<REG_N>", "0011nnnnmmmm1000", "R[n]-=R[m];"},
193 {"n","nm","subc <REG_M>,<REG_N>", "0011nnnnmmmm1010", "ult=R[n]-T;T=ult>R[n];R[n]=ult-R[m];T|=R[n]>ult;"},
194 {"n","nm","subv <REG_M>,<REG_N>", "0011nnnnmmmm1011",
195 "ult = R[n] - R[m]; T = (((R[n] ^ R[m]) & (ult ^ R[n])) >> 31); R[n] = ult;"},
196 {"n","nm","swap.b <REG_M>,<REG_N>", "0110nnnnmmmm1000", "R[n]=((R[m]<<8)&0xff00)|((R[m]>>8)&0x00ff);"},
197 {"n","nm","swap.w <REG_M>,<REG_N>", "0110nnnnmmmm1001", "R[n]=((R[m]<<16)&0xffff0000)|((R[m]>>16)&0x00ffff);"},
198 {"","n","tas.b @<REG_N>", "0100nnnn00011011", "ult=RBAT(R[n]);T=ult==0;WBAT(R[n],ult|0x80);"},
199 {"0","","trapa #<imm>", "11000011i8*1....",
200 "{ long imm = 0xff & i; if (i==0xc3) PC-=2; if (i<20||i==34||i==0xc3) trap(i,R,memory,maskl,maskw,little_endian); else { R[15]-=4; WLAT(R[15],GET_SR()); R[15]-=4;WLAT(R[15],PC+2); PC=RLAT(VBR+(imm<<2))-2;}}"},
201 {"","0","tst #<imm>,R0", "11001000i8*1....", "T=(R0&i)==0;"},
202 {"","mn","tst <REG_M>,<REG_N>", "0010nnnnmmmm1000", "T=(R[n]&R[m])==0;"},
203 {"","0","tst.b #<imm>,@(R0,GBR)", "11001100i8*1....", "T=(RBAT(GBR+R0)&i)==0;"},
204 {"","0","xor #<imm>,R0", "11001010i8*1....", "R0^=i;"},
205 {"n","mn","xor <REG_M>,<REG_N>", "0010nnnnmmmm1010", "R[n]^=R[m];"},
206 {"","0","xor.b #<imm>,@(R0,GBR)", "11001110i8*1....", "ult=RBAT(GBR+R0);ult^=i;WBAT(GBR+R0,ult);"},
207 {"n","nm","xtrct <REG_M>,<REG_N>", "0010nnnnmmmm1101", "R[n]=((R[n]>>16)&0xffff)|((R[m]<<16)&0xffff0000);"},
208 {"","nm","mul.l <REG_M>,<REG_N>", "0000nnnnmmmm0111", " MACL = R[n] * R[m];"},
209 {"n","n","dt <REG_N>", "0100nnnn00010000", "R[n]--; T=R[n] == 0;"},
210 {"","nm","dmuls.l <REG_M>,<REG_N>", "0011nnnnmmmm1101", "dmul(1,R[n],R[m]);"},
211 {"","nm","dmulu.l <REG_M>,<REG_N>", "0011nnnnmmmm0101", "dmul(0,R[n],R[m]);"},
212 {"","nm","mac.l @<REG_M>+,@<REG_N>+", "0000nnnnmmmm1111", "abort();"},
213 {"","n","braf <REG_N>", "0000nnnn00100011", "ult = PC; PC+=R[n]-2;SL(ult+2);"},
214 {"","n","bsrf <REG_N>", "0000nnnn00000011", "PR = PC + 4; PC+=R[n]-2;SL(PR-2);"},
215 #if 0
216 {"divs.l <REG_M>,<REG_N>", "0100nnnnmmmm1110", "divl(0,R[n],R[m]);"},
217 {"divu.l <REG_M>,<REG_N>", "0100nnnnmmmm1101", "divl(0,R[n],R[m]);"},
218 #endif
219
220 /* start-sanitize-sh3e */
221 {"", "", "fmov.s @<REG_M>,<FREG_N>", "1111nnnnmmmm1000", "*(int *)buf = RLAT(R[m]);F[n] = *(float *)buf;"},
222 {"", "", "fmov.s <FREG_M>,@<REG_N>", "1111nnnnmmmm1010", "*(float *)buf = F[m]; WLAT(R[n], *(int *)buf);"},
223 {"", "", "fmov.s @<REG_M>+,<FREG_N>", "1111nnnnmmmm1001", "*(int *)buf = RLAT(R[m]); F[n] = *(float *)buf; R[m] += 4;"},
224 {"", "", "fmov.s <FREG_M>,@-<REG_N>", "1111nnnnmmmm1011", "R[n] -= 4; *(float *)buf = F[m]; WLAT(R[n], *(int *)buf);"},
225 {"", "", "fmov.s @(R0,<REG_M>),<FREG_N>", "1111nnnnmmmm0110", "*(int *)buf = RLAT((R[0]+R[m]));F[n] = *(float *)buf;"},
226 {"", "", "fmov.s <FREG_M>,@(R0,<REG_N>)", "1111nnnnmmmm0111", "*(float *)buf = F[m]; WLAT((R[0]+R[n]), *(int *)buf);"},
227 {"", "", "fmov <FREG_M>,<FREG_N>", "1111nnnnmmmm1100", "F[n] = F[m];"},
228 {"", "", "fldi0 <FREG_N>", "1111nnnn10001101", "F[n] = (float)0.0;"},
229 {"", "", "fldi1 <FREG_N>", "1111nnnn10011101", "F[n] = (float)1.0;"},
230 {"", "", "fadd <FREG_M>,<FREG_N>", "1111nnnnmmmm0000","F[n] = F[n] + F[m];"},
231 {"", "", "fsub <FREG_M>,<FREG_N>", "1111nnnnmmmm0001","F[n] = F[n] - F[m];"},
232 {"", "", "fmul <FREG_M>,<FREG_N>", "1111nnnnmmmm0010","F[n] = F[n] * F[m];"},
233 {"", "", "fdiv <FREG_M>,<FREG_N>", "1111nnnnmmmm0011","F[n] = F[n] / F[m];"},
234 {"", "", "fmac <FREG_0>,<FREG_M>,<FREG_N>", "1111nnnnmmmm1110", "F[n] = F[m] * F[0] + F[n];"},
235 {"", "", "fcmp/eq <FREG_M>,<FREG_N>", "1111nnnnmmmm0100", "T = F[n] == F[m] ? 1 : 0;"},
236 {"", "", "fcmp/gt <FREG_M>,<FREG_N>", "1111nnnnmmmm0101", "T = F[n] > F[m] ? 1 : 0;"},
237 {"", "", "fneg <FREG_N>", "1111nnnn01001101", "F[n] = -F[n];"},
238 {"", "", "fabs <FREG_N>", "1111nnnn01011101", "F[n] = fabs (F[n]);"},
239 {"", "", "fsqrt <FREG_N>", "1111nnnn01101101", "F[n] = sqrt (F[n]);"},
240 {"", "", "float FPUL,<FREG_N>", "1111nnnn00101101", "F[n] = (float)FPUL;"},
241 {"", "", "ftrc <FREG_N>, FPUL", "1111nnnn00111101", "if (F[n] != F[n]) /* NaN */ FPUL = 0x80000000; else FPUL = (int)F[n];"},
242 {"", "", "ftst/nan <FREG_N>", "1111nnnn01111101", "T = isnan (F[n]);"},
243 {"", "", "fsts FPUL,<FREG_N>", "1111nnnn00001101", "*(int *)buf = FPUL; F[n] = *(float *)buf;"},
244 {"", "", "flds <FREG_N>,FPUL", "1111nnnn00011101", "*(float *)buf = F[n]; FPUL = *(int *)buf;"},
245 {"", "", "lds <REG_N>,FPUL", "0100nnnn01011010", "FPUL = R[n];"},
246 {"", "", "sts FPUL,<REG_N>", "0000nnnn01011010", "R[n] = FPUL;"},
247 {"", "", "lds <REG_N>,FPSCR", "0100nnnn01101010", "*(int *)buf = R[n]; FPSCR = *(float *)buf;"},
248 {"", "", "sts FPSCR,<REG_N>", "0000nnnn01101010", "*(float *)buf = FPSCR; R[n] = *(int *)buf;"},
249 {"","","lds.l @<REG_N>+,FPUL", "0100nnnn01010110", "FPUL = RLAT(R[n]);R[n]+=4;"},
250 {"","","lds.l @<REG_N>+,FPSCR", "0100nnnn01100110", "*(int *)buf = RLAT(R[n]); FPSCR = *(float *)buf; R[n]+=4;"},
251 {"","","sts.l FPUL,@-<REG_N>", "0100nnnn01010010", "R[n]-=4;WLAT(R[n],FPUL);"},
252 {"","","sts.l FPSCR,@-<REG_N>", "0100nnnn01100010", "R[n]-=4;*(float *)buf = FPSCR; WLAT(R[n],*(int *)buf);"},
253 /* end-sanitize-sh3e */
254
255 {0, 0}};
256
257 /* Tables of things to put into enums for sh-opc.h */
258 static char *nibble_type_list[] =
259 {
260 "HEX_0",
261 "HEX_1",
262 "HEX_2",
263 "HEX_3",
264 "HEX_4",
265 "HEX_5",
266 "HEX_6",
267 "HEX_7",
268 "HEX_8",
269 "HEX_9",
270 "HEX_A",
271 "HEX_B",
272 "HEX_C",
273 "HEX_D",
274 "HEX_E",
275 "HEX_F",
276 "REG_N",
277 "REG_M",
278 "BRANCH_12",
279 "BRANCH_8",
280 "DISP_8",
281 "DISP_4",
282 "IMM_4",
283 "IMM_4BY2",
284 "IMM_4BY4",
285 "PCRELIMM_8BY2",
286 "PCRELIMM_8BY4",
287 "IMM_8",
288 "IMM_8BY2",
289 "IMM_8BY4",
290 0
291 };
292 static
293 char *arg_type_list[] =
294 {
295 "A_END",
296 "A_BDISP12",
297 "A_BDISP8",
298 "A_DEC_M",
299 "A_DEC_N",
300 "A_DISP_GBR",
301 "A_DISP_PC",
302 "A_DISP_REG_M",
303 "A_DISP_REG_N",
304 "A_GBR",
305 "A_IMM",
306 "A_INC_M",
307 "A_INC_N",
308 "A_IND_M",
309 "A_IND_N",
310 "A_IND_R0_REG_M",
311 "A_IND_R0_REG_N",
312 "A_MACH",
313 "A_MACL",
314 "A_PR",
315 "A_R0",
316 "A_R0_GBR",
317 "A_REG_M",
318 "A_REG_N",
319 "A_SR",
320 "A_VBR",
321 "A_SSR",
322 "A_SPC",
323 0,
324 };
325
326 static void
327 make_enum_list (name, s)
328 char *name;
329 char **s;
330 {
331 int i = 1;
332 printf ("typedef enum {\n");
333 while (*s)
334 {
335 printf ("\t%s,\n", *s);
336 s++;
337 i++;
338 }
339 printf ("} %s;\n", name);
340 }
341
342 static int
343 qfunc (a, b)
344 op *a;
345 op *b;
346 {
347 char bufa[9];
348 char bufb[9];
349 memcpy (bufa, a->code, 4);
350 memcpy (bufa + 4, a->code + 12, 4);
351 bufa[8] = 0;
352
353 memcpy (bufb, b->code, 4);
354 memcpy (bufb + 4, b->code + 12, 4);
355 bufb[8] = 0;
356 return (strcmp (bufa, bufb));
357 }
358
359 static void
360 sorttab ()
361 {
362 op *p = tab;
363 int len = 0;
364
365 while (p->name)
366 {
367 p++;
368 len++;
369 }
370 qsort (tab, len, sizeof (*p), qfunc);
371 }
372
373 static void
374 printonmatch (ptr, a, rep)
375 char **ptr;
376 char *a;
377 char *rep;
378 {
379 int l = strlen (a);
380 if (strncmp (*ptr, a, l) == 0)
381 {
382 printf ("%s", rep);
383 *ptr += l;
384 if (**ptr)
385 printf (",");
386 }
387 }
388
389
390 static
391 void
392 think (o)
393 op *o;
394 {
395 char *n;
396 char *p;
397
398 printf ("{\"");
399 n = o->name;
400 while (*n && *n != ' ')
401 {
402 printf ("%c", *n);
403 n++;
404 }
405 printf ("\",{");
406
407 p = n;
408
409 if (!*p)
410 {
411 printf ("0");
412 }
413 while (*p)
414 {
415 while (*p == ',' || *p == ' ')
416 p++;
417 printonmatch (&p, "#<imm>", "A_IMM");
418 printonmatch (&p, "R0", "A_R0");
419 printonmatch (&p, "<REG_N>", "A_REG_N");
420 printonmatch (&p, "@<REG_N>+", "A_INC_N");
421 printonmatch (&p, "@<REG_N>", "A_IND_N");
422 printonmatch (&p, "@-<REG_N>", "A_DEC_N");
423 printonmatch (&p, "<REG_M>", " A_REG_M");
424 printonmatch (&p, "@<REG_M>+", "A_INC_M");
425 printonmatch (&p, "@<REG_M>", "A_IND_M");
426 printonmatch (&p, "@-<REG_M>", "A_DEC_M");
427 printonmatch (&p, "@(<disp>,PC)", "A_DISP_PC");
428 printonmatch (&p, "@(<disp>,<REG_M>)", "A_DISP_REG_M");
429 printonmatch (&p, "@(<disp>,<REG_N>)", "A_DISP_REG_N");
430 printonmatch (&p, "@(R0,<REG_N>)", "A_IND_R0_REG_N");
431 printonmatch (&p, "@(R0,<REG_M>)", "A_IND_R0_REG_M");
432 printonmatch (&p, "@(<disp>,GBR)", "A_DISP_GBR");
433 printonmatch (&p, "@(R0,GBR)", "A_R0_GBR");
434 printonmatch (&p, "<bdisp8>", "A_BDISP8");
435 printonmatch (&p, "<bdisp12>", "A_BDISP12");
436 printonmatch (&p, "SR", "A_SR");
437 printonmatch (&p, "GBR", "A_GBR");
438 printonmatch (&p, "VBR", "A_VBR");
439 printonmatch (&p, "SSR", "A_SSR");
440 printonmatch (&p, "SPC", "A_SPC");
441 printonmatch (&p, "MACH", "A_MACH");
442 printonmatch (&p, "MACL", "A_MACL");
443 printonmatch (&p, "PR", "A_PR");
444
445 }
446 printf ("},{");
447
448 p = o->code;
449 while (*p)
450 {
451 printonmatch (&p, "0000", "HEX_0");
452 printonmatch (&p, "0001", "HEX_1");
453 printonmatch (&p, "0010", "HEX_2");
454 printonmatch (&p, "0011", "HEX_3");
455 printonmatch (&p, "0100", "HEX_4");
456 printonmatch (&p, "0101", "HEX_5");
457 printonmatch (&p, "0110", "HEX_6");
458 printonmatch (&p, "0111", "HEX_7");
459
460 printonmatch (&p, "1000", "HEX_8");
461 printonmatch (&p, "1001", "HEX_9");
462 printonmatch (&p, "1010", "HEX_A");
463 printonmatch (&p, "1011", "HEX_B");
464 printonmatch (&p, "1100", "HEX_C");
465 printonmatch (&p, "1101", "HEX_D");
466 printonmatch (&p, "1110", "HEX_E");
467 printonmatch (&p, "1111", "HEX_F");
468 printonmatch (&p, "i8*1....", "IMM_8");
469 printonmatch (&p, "i4*1", "IMM_4");
470 printonmatch (&p, "i8p4....", "PCRELIMM_8BY4");
471 printonmatch (&p, "i8p2....", "PCRELIMM_8BY2");
472 printonmatch (&p, "i8*2....", "IMM_8BY2");
473 printonmatch (&p, "i4*2", "IMM_4BY2");
474 printonmatch (&p, "i8*4....", "IMM_8BY4");
475 printonmatch (&p, "i4*4", "IMM_4BY4");
476 printonmatch (&p, "i12.........", "BRANCH_12");
477 printonmatch (&p, "i8p1....", "BRANCH_8");
478 printonmatch (&p, "nnnn", "REG_N");
479 printonmatch (&p, "mmmm", "REG_M");
480
481 }
482 printf ("}},\n");
483 }
484
485 static void
486 gengastab ()
487 {
488 op *p;
489 sorttab ();
490 for (p = tab; p->name; p++)
491 {
492 printf ("%s %-30s\n", p->code, p->name);
493 }
494
495
496 }
497
498
499 static void
500 genopc ()
501 {
502 op *p;
503 make_enum_list ("sh_nibble_type", nibble_type_list);
504 make_enum_list ("sh_arg_type", arg_type_list);
505
506 printf ("typedef struct {\n");
507 printf ("char *name;\n");
508 printf ("sh_arg_type arg[3];\n");
509 printf ("sh_nibble_type nibbles[4];\n");
510 printf ("} sh_opcode_info;\n");
511 printf ("#ifdef DEFINE_TABLE\n");
512 printf ("sh_opcode_info sh_table[]={\n");
513 for (p = tab; p->name; p++)
514 {
515 printf ("\n/* %s %-20s*/", p->code, p->name);
516 think (p);
517 }
518 printf ("0};\n");
519 printf ("#endif\n");
520 }
521
522
523
524
525
526
527 /* Convert a string of 4 binary digits into an int */
528
529 static
530 int
531 bton (s)
532 char *s;
533
534 {
535 int n = 0;
536 int v = 8;
537 while (v)
538 {
539 if (*s == '1')
540 n |= v;
541 v >>= 1;
542 s++;
543 }
544 return n;
545 }
546
547 static unsigned char table[1 << 16];
548
549 /* Take an opcode expand all varying fields in it out and fill all the
550 right entries in 'table' with the opcode index*/
551
552 static void
553 expand_opcode (shift, val, i, s)
554 int shift;
555 int val;
556 int i;
557 char *s;
558 {
559 int j;
560
561 if (*s == 0)
562 {
563 table[val] = i;
564 }
565 else
566 {
567 switch (s[0])
568 {
569
570 case '0':
571 case '1':
572 {
573
574 int n = bton (s);
575 if (n >= 0)
576 {
577 expand_opcode (shift - 4, val | (n << shift), i, s + 4);
578 }
579 break;
580 }
581 case 'n':
582 case 'm':
583 for (j = 0; j < 16; j++)
584 {
585 expand_opcode (shift - 4, val | (j << shift), i, s + 4);
586
587 }
588 break;
589
590 default:
591 for (j = 0; j < (1 << (shift + 4)); j++)
592 {
593 table[val | j] = i;
594 }
595 }
596 }
597 }
598
599 /* Print the jump table used to index an opcode into a switch
600 statement entry. */
601
602 static void
603 dumptable ()
604 {
605 int lump = 256;
606 int online = 16;
607
608 int i = 0;
609
610 while (i < 1 << 16)
611 {
612 int j = 0;
613
614 printf ("unsigned char sh_jump_table%x[%d]={\n", i, lump);
615
616 while (j < lump)
617 {
618 int k = 0;
619 while (k < online)
620 {
621 printf ("%2d", table[i + j + k]);
622 if (j + k < lump)
623 printf (",");
624
625 k++;
626 }
627 j += k;
628 printf ("\n");
629 }
630 i += j;
631 printf ("};\n");
632 }
633
634 }
635
636
637 static void
638 filltable ()
639 {
640 op *p;
641 int index = 1;
642
643 sorttab ();
644 for (p = tab; p->name; p++)
645 {
646 p->index = index++;
647 expand_opcode (12, 0, p->index, p->code);
648 }
649 }
650
651 static void
652 gensim ()
653 {
654 op *p;
655 int j;
656
657 printf ("{\n");
658 /* start-sanitize-sh3e */
659 printf("char buf[4];\n");
660 /* end-sanitize-sh3e */
661 printf ("switch (jump_table[iword]) {\n");
662
663 for (p = tab; p->name; p++)
664 {
665 int sextbit = -1;
666 int needm = 0;
667 int needn = 0;
668
669 char *s = p->code;
670
671 printf ("/* %s %s */\n", p->name, p->code);
672 printf ("case %d: \n", p->index);
673
674 printf ("{\n");
675 while (*s)
676 {
677 switch (*s)
678 {
679 case '0':
680 case '1':
681 case '.':
682 s += 4;
683 break;
684 case 'n':
685 printf ("int n = (iword >>8) & 0xf;\n");
686 needn = 1;
687 s += 4;
688 break;
689 case 'm':
690 printf ("int m = (iword >>4) & 0xf;\n");
691 needm = 1;
692 s += 4;
693
694 break;
695
696 case 'i':
697 printf ("int i = (iword & 0x");
698
699 switch (s[1])
700 {
701 case '4':
702 printf ("f");
703 break;
704 case '8':
705 printf ("ff");
706 break;
707 case '1':
708 sextbit = 12;
709
710 printf ("fff");
711 break;
712 }
713 printf (")");
714
715 switch (s[3])
716 {
717 case '1':
718 break;
719 case '2':
720 printf ("<<1");
721 break;
722 case '4':
723 printf ("<<2");
724 break;
725 }
726 printf (";\n");
727 s += 4;
728 }
729 }
730 if (sextbit > 0)
731 {
732 printf ("i = (i ^ (1<<%d))-(1<<%d);\n", sextbit - 1, sextbit - 1);
733 }
734 if (needm && needn)
735 printf("TB(m,n);");
736 else if (needm)
737 printf("TL(m);");
738 else if (needn)
739 printf("TL(n);");
740 for (j = 0; j < 10; j++)
741 {
742 if (p->stuff[j])
743 {
744 printf ("%s\n", p->stuff[j]);
745 }
746 }
747
748
749 {
750 /* Do the defs and refs */
751 char *r;
752 for (r = p->refs; *r; r++) {
753 if (*r == '0') printf("CREF(0);\n");
754 if (*r == 'n') printf("CREF(n);\n");
755 if (*r == 'm') printf("CREF(m);\n");
756
757 }
758 for (r = p->defs; *r; r++)
759 {
760 if (*r == '0') printf("CDEF(0);\n");
761 if (*r == 'n') printf("CDEF(n);\n");
762 if (*r == 'm') printf("CDEF(m);\n");
763
764 }
765
766 }
767 printf ("break;\n");
768 printf ("}\n");
769 }
770 printf("default:\n{\nsaved_state.asregs.exception = SIGILL;\n}\n");
771 printf ("}\n}\n");
772 }
773
774
775 static void
776 gendefines ()
777 {
778 op *p;
779 filltable();
780 for (p = tab; p->name; p++)
781 {
782 char *s = p->name;
783 printf ("#define OPC_");
784 while (*s) {
785 if (isupper(*s))
786 *s = tolower(*s);
787 if (isalpha(*s)) printf("%c", *s);
788 if (*s == ' ') printf("_");
789 if (*s == '@') printf("ind_");
790 if (*s == ',') printf("_");
791 s++;
792 }
793 printf(" %d\n",p->index);
794 }
795 }
796
797 int
798 main (ac, av)
799 int ac;
800 char **av;
801 {
802 if (ac > 1)
803 {
804 if (strcmp (av[1], "-t") == 0)
805 {
806 gengastab ();
807 }
808 else if (strcmp (av[1], "-d") == 0)
809 {
810 gendefines ();
811 }
812 else if (strcmp (av[1], "-s") == 0)
813 {
814 filltable ();
815 dumptable ();
816
817 }
818 else if (strcmp (av[1], "-x") == 0)
819 {
820 filltable ();
821 gensim ();
822 }
823 }
824 else
825 {
826 genopc ();
827 }
828 return 0;
829 }
This page took 0.062133 seconds and 4 git commands to generate.