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