* gencode.c (gensim): abort if an unknown opcode is encountered.
[deliverable/binutils-gdb.git] / sim / sh / gencode.c
CommitLineData
594266fc
SC
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
acae2683 26 -d generates a define table
594266fc
SC
27 -x generates the simulator code switch statement
28 default generates the opcode tables
29
30*/
31
acae2683
TG
32#include <stdio.h>
33
594266fc
SC
34typedef struct
35{
acae2683
TG
36char *defs;
37char *refs;
594266fc
SC
38 char *name;
39 char *code;
40 char *stuff[10];
41 int index;
42}
43
44op;
45
46
47op tab[] =
48{
49
acae2683
TG
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];"},
a43b22b5
SC
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;"},
acae2683 54 {"n","mn","addv <REG_M>,<REG_N>", "0011nnnnmmmm1111",
a43b22b5 55 "ult = R[n] + R[m]; T = ((~(R[n] ^ R[m]) & (ult ^ R[n])) >> 31); R[n] = ult;"},
acae2683
TG
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; 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; 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;;"},
a43b22b5 99 {"","n","mac.w @<REG_M>+,@<REG_N>+", "0100nnnnmmmm1111", "macw(R0,memory,n,m);"},
acae2683
TG
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];"},
a43b22b5 140 {"n","m","negc <REG_M>,<REG_N>", "0110nnnnmmmm1010", "ult=-T;T=ult>0;R[n]=ult-R[m];T|=R[n]>ult;"},
acae2683
TG
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+2;SL(ult+2);"},
153 {"","","sett", "0000000000011000", "T=1;"},
acae2683
TG
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)) ;"},
acae2683
TG
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)) ;"},
acae2683
TG
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];"},
a43b22b5
SC
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;"},
acae2683
TG
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....",
2ca7c3c4 189 "{ long imm = 0xff & i; 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;}}"},
acae2683
TG
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]);"},
a43b22b5
SC
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; PC+=R[n]-2;SL(PR+2);"},
594266fc 204#if 0
acae2683
TG
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]);"},
594266fc
SC
207#endif
208
209 {0, 0}};
210
211/* Tables of things to put into enums for sh-opc.h */
212static char *nibble_type_list[] =
213{
214 "HEX_0",
215 "HEX_1",
216 "HEX_2",
217 "HEX_3",
218 "HEX_4",
219 "HEX_5",
220 "HEX_6",
221 "HEX_7",
222 "HEX_8",
223 "HEX_9",
224 "HEX_A",
225 "HEX_B",
226 "HEX_C",
227 "HEX_D",
228 "HEX_E",
229 "HEX_F",
230 "REG_N",
231 "REG_M",
232 "BRANCH_12",
233 "BRANCH_8",
234 "DISP_8",
235 "DISP_4",
236 "IMM_4",
237 "IMM_4BY2",
238 "IMM_4BY4",
239 "PCRELIMM_8BY2",
240 "PCRELIMM_8BY4",
241 "IMM_8",
242 "IMM_8BY2",
243 "IMM_8BY4",
244 0
245};
246static
247char *arg_type_list[] =
248{
249 "A_END",
250 "A_BDISP12",
251 "A_BDISP8",
252 "A_DEC_M",
253 "A_DEC_N",
254 "A_DISP_GBR",
255 "A_DISP_PC",
256 "A_DISP_REG_M",
257 "A_DISP_REG_N",
258 "A_GBR",
259 "A_IMM",
260 "A_INC_M",
261 "A_INC_N",
262 "A_IND_M",
263 "A_IND_N",
264 "A_IND_R0_REG_M",
265 "A_IND_R0_REG_N",
266 "A_MACH",
267 "A_MACL",
268 "A_PR",
269 "A_R0",
270 "A_R0_GBR",
271 "A_REG_M",
272 "A_REG_N",
273 "A_SR",
274 "A_VBR",
275 0,
276};
277
278static void
279make_enum_list (name, s)
280 char *name;
281 char **s;
282{
283 int i = 1;
284 printf ("typedef enum {\n");
285 while (*s)
286 {
acae2683 287 printf ("\t%s,\n", *s);
594266fc
SC
288 s++;
289 i++;
290 }
291 printf ("} %s;\n", name);
292}
293
acae2683
TG
294static int
295qfunc (a, b)
296 op *a;
297 op *b;
594266fc 298{
acae2683
TG
299 char bufa[9];
300 char bufb[9];
301 memcpy (bufa, a->code, 4);
302 memcpy (bufa + 4, a->code + 12, 4);
303 bufa[8] = 0;
594266fc 304
acae2683
TG
305 memcpy (bufb, b->code, 4);
306 memcpy (bufb + 4, b->code + 12, 4);
307 bufb[8] = 0;
308 return (strcmp (bufa, bufb));
594266fc
SC
309}
310
acae2683
TG
311static void
312sorttab ()
594266fc 313{
acae2683
TG
314 op *p = tab;
315 int len = 0;
594266fc 316
acae2683 317 while (p->name)
594266fc 318 {
acae2683
TG
319 p++;
320 len++;
594266fc 321 }
acae2683 322 qsort (tab, len, sizeof (*p), qfunc);
594266fc
SC
323}
324
acae2683
TG
325static void
326printonmatch (ptr, a, rep)
594266fc
SC
327 char **ptr;
328 char *a;
329 char *rep;
330{
331 int l = strlen (a);
332 if (strncmp (*ptr, a, l) == 0)
333 {
334 printf ("%s", rep);
335 *ptr += l;
336 if (**ptr)
337 printf (",");
338 }
339}
340
acae2683
TG
341
342static
343void
594266fc
SC
344think (o)
345 op *o;
346{
594266fc
SC
347 char *n;
348 char *p;
349
350 printf ("{\"");
351 n = o->name;
352 while (*n && *n != ' ')
353 {
354 printf ("%c", *n);
355 n++;
356 }
357 printf ("\",{");
358
359 p = n;
360
361 if (!*p)
362 {
363 printf ("0");
364 }
365 while (*p)
366 {
367 while (*p == ',' || *p == ' ')
368 p++;
acae2683
TG
369 printonmatch (&p, "#<imm>", "A_IMM");
370 printonmatch (&p, "R0", "A_R0");
371 printonmatch (&p, "<REG_N>", "A_REG_N");
372 printonmatch (&p, "@<REG_N>+", "A_INC_N");
373 printonmatch (&p, "@<REG_N>", "A_IND_N");
374 printonmatch (&p, "@-<REG_N>", "A_DEC_N");
375 printonmatch (&p, "<REG_M>", " A_REG_M");
376 printonmatch (&p, "@<REG_M>+", "A_INC_M");
377 printonmatch (&p, "@<REG_M>", "A_IND_M");
378 printonmatch (&p, "@-<REG_M>", "A_DEC_M");
379 printonmatch (&p, "@(<disp>,PC)", "A_DISP_PC");
380 printonmatch (&p, "@(<disp>,<REG_M>)", "A_DISP_REG_M");
381 printonmatch (&p, "@(<disp>,<REG_N>)", "A_DISP_REG_N");
382 printonmatch (&p, "@(R0,<REG_N>)", "A_IND_R0_REG_N");
383 printonmatch (&p, "@(R0,<REG_M>)", "A_IND_R0_REG_M");
384 printonmatch (&p, "@(<disp>,GBR)", "A_DISP_GBR");
385 printonmatch (&p, "@(R0,GBR)", "A_R0_GBR");
386 printonmatch (&p, "<bdisp8>", "A_BDISP8");
387 printonmatch (&p, "<bdisp12>", "A_BDISP12");
388 printonmatch (&p, "SR", "A_SR");
389 printonmatch (&p, "GBR", "A_GBR");
390 printonmatch (&p, "VBR", "A_VBR");
391 printonmatch (&p, "MACH", "A_MACH");
392 printonmatch (&p, "MACL", "A_MACL");
393 printonmatch (&p, "PR", "A_PR");
594266fc
SC
394
395 }
396 printf ("},{");
397
398 p = o->code;
399 while (*p)
400 {
acae2683
TG
401 printonmatch (&p, "0000", "HEX_0");
402 printonmatch (&p, "0001", "HEX_1");
403 printonmatch (&p, "0010", "HEX_2");
404 printonmatch (&p, "0011", "HEX_3");
405 printonmatch (&p, "0100", "HEX_4");
406 printonmatch (&p, "0101", "HEX_5");
407 printonmatch (&p, "0110", "HEX_6");
408 printonmatch (&p, "0111", "HEX_7");
409
410 printonmatch (&p, "1000", "HEX_8");
411 printonmatch (&p, "1001", "HEX_9");
412 printonmatch (&p, "1010", "HEX_A");
413 printonmatch (&p, "1011", "HEX_B");
414 printonmatch (&p, "1100", "HEX_C");
415 printonmatch (&p, "1101", "HEX_D");
416 printonmatch (&p, "1110", "HEX_E");
417 printonmatch (&p, "1111", "HEX_F");
418 printonmatch (&p, "i8*1....", "IMM_8");
419 printonmatch (&p, "i4*1", "IMM_4");
420 printonmatch (&p, "i8p4....", "PCRELIMM_8BY4");
421 printonmatch (&p, "i8p2....", "PCRELIMM_8BY2");
422 printonmatch (&p, "i8*2....", "IMM_8BY2");
423 printonmatch (&p, "i4*2", "IMM_4BY2");
424 printonmatch (&p, "i8*4....", "IMM_8BY4");
425 printonmatch (&p, "i4*4", "IMM_4BY4");
426 printonmatch (&p, "i12.........", "BRANCH_12");
427 printonmatch (&p, "i8p1....", "BRANCH_8");
428 printonmatch (&p, "nnnn", "REG_N");
429 printonmatch (&p, "mmmm", "REG_M");
594266fc
SC
430
431 }
432 printf ("}},\n");
433}
434
acae2683
TG
435static void
436gengastab ()
594266fc 437{
acae2683
TG
438 op *p;
439 sorttab ();
440 for (p = tab; p->name; p++)
441 {
442 printf ("%s %-30s\n", p->code, p->name);
443 }
444
594266fc 445
594266fc
SC
446}
447
448
acae2683
TG
449static void
450genopc ()
594266fc 451{
acae2683
TG
452 op *p;
453 make_enum_list ("sh_nibble_type", nibble_type_list);
454 make_enum_list ("sh_arg_type", arg_type_list);
594266fc 455
acae2683
TG
456 printf ("typedef struct {\n");
457 printf ("char *name;\n");
458 printf ("sh_arg_type arg[3];\n");
459 printf ("sh_nibble_type nibbles[4];\n");
460 printf ("} sh_opcode_info;\n");
461 printf ("#ifdef DEFINE_TABLE\n");
462 printf ("sh_opcode_info sh_table[]={\n");
463 for (p = tab; p->name; p++)
594266fc 464 {
2ca7c3c4 465 printf ("\n/* %s %-20s*/", p->code, p->name);
acae2683 466 think (p);
594266fc 467 }
acae2683
TG
468 printf ("0};\n");
469 printf ("#endif\n");
470}
471
472
473
594266fc 474
594266fc 475
594266fc
SC
476
477/* Convert a string of 4 binary digits into an int */
478
479static
480int
481bton (s)
482 char *s;
483
484{
485 int n = 0;
486 int v = 8;
487 while (v)
488 {
489 if (*s == '1')
490 n |= v;
491 v >>= 1;
492 s++;
493 }
494 return n;
495}
496
acae2683 497static unsigned char table[1 << 16];
594266fc 498
acae2683 499/* Take an opcode expand all varying fields in it out and fill all the
594266fc 500 right entries in 'table' with the opcode index*/
acae2683
TG
501
502static void
594266fc 503expand_opcode (shift, val, i, s)
acae2683
TG
504 int shift;
505 int val;
506 int i;
594266fc
SC
507 char *s;
508{
509 int j;
510
511 if (*s == 0)
512 {
513 table[val] = i;
514 }
515 else
516 {
517 switch (s[0])
518 {
519
520 case '0':
521 case '1':
522 {
523
524 int n = bton (s);
525 if (n >= 0)
526 {
527 expand_opcode (shift - 4, val | (n << shift), i, s + 4);
528 }
529 break;
530 }
531 case 'n':
532 case 'm':
533 for (j = 0; j < 16; j++)
534 {
535 expand_opcode (shift - 4, val | (j << shift), i, s + 4);
536
537 }
538 break;
539
540 default:
541 for (j = 0; j < (1 << (shift + 4)); j++)
542 {
543 table[val | j] = i;
544 }
545 }
546 }
547}
548
549/* Print the jump table used to index an opcode into a switch
acae2683 550 statement entry. */
594266fc 551
acae2683 552static void
594266fc
SC
553dumptable ()
554{
555 int lump = 256;
556 int online = 16;
557
558 int i = 0;
559
560 while (i < 1 << 16)
561 {
562 int j = 0;
594266fc
SC
563
564 printf ("unsigned char sh_jump_table%x[%d]={\n", i, lump);
565
566 while (j < lump)
567 {
568 int k = 0;
569 while (k < online)
570 {
571 printf ("%2d", table[i + j + k]);
572 if (j + k < lump)
573 printf (",");
574
575 k++;
576 }
577 j += k;
578 printf ("\n");
579 }
580 i += j;
581 printf ("};\n");
582 }
583
584}
585
586
587static void
588filltable ()
589{
590 op *p;
591 int index = 1;
592
593 sorttab ();
594 for (p = tab; p->name; p++)
595 {
596 p->index = index++;
597 expand_opcode (12, 0, p->index, p->code);
598 }
599}
600
acae2683 601static void
594266fc
SC
602gensim ()
603{
604 op *p;
605 int j;
606
607 printf ("{\n");
608 printf ("switch (jump_table[iword]) {\n");
609
610 for (p = tab; p->name; p++)
611 {
612 int sextbit = -1;
acae2683
TG
613 int needm = 0;
614 int needn = 0;
615
594266fc
SC
616 char *s = p->code;
617
2ca7c3c4 618 printf ("/* %s %s */\n", p->name, p->code);
594266fc
SC
619 printf ("case %d: \n", p->index);
620
621 printf ("{\n");
622 while (*s)
623 {
624 switch (*s)
625 {
626 case '0':
627 case '1':
628 case '.':
629 s += 4;
630 break;
631 case 'n':
632 printf ("int n = (iword >>8) & 0xf;\n");
acae2683 633 needn = 1;
594266fc
SC
634 s += 4;
635 break;
636 case 'm':
637 printf ("int m = (iword >>4) & 0xf;\n");
acae2683 638 needm = 1;
594266fc
SC
639 s += 4;
640
641 break;
642
643 case 'i':
644 printf ("int i = (iword & 0x");
645
646 switch (s[1])
647 {
648 case '4':
649 printf ("f");
650 break;
651 case '8':
652 printf ("ff");
653 break;
654 case '1':
655 sextbit = 12;
acae2683 656
594266fc
SC
657 printf ("fff");
658 break;
659 }
660 printf (")");
661
662 switch (s[3])
663 {
664 case '1':
665 break;
666 case '2':
667 printf ("<<1");
668 break;
669 case '4':
670 printf ("<<2");
671 break;
672 }
673 printf (";\n");
674 s += 4;
675 }
676 }
acae2683 677 if (sextbit > 0)
594266fc 678 {
acae2683 679 printf ("i = (i ^ (1<<%d))-(1<<%d);\n", sextbit - 1, sextbit - 1);
594266fc 680 }
acae2683
TG
681 if (needm && needn)
682 printf("TB(m,n);");
683 else if (needm)
684 printf("TL(m);");
685 else if (needn)
686 printf("TL(n);");
594266fc
SC
687 for (j = 0; j < 10; j++)
688 {
689 if (p->stuff[j])
690 {
691 printf ("%s\n", p->stuff[j]);
692 }
693 }
acae2683
TG
694
695
696 {
697 /* Do the defs and refs */
698 char *r;
699 for (r = p->refs; *r; r++) {
700 if (*r == '0') printf("CREF(0);\n");
701 if (*r == 'n') printf("CREF(n);\n");
702 if (*r == 'm') printf("CREF(m);\n");
703
704 }
705 for (r = p->defs; *r; r++)
706 {
707 if (*r == '0') printf("CDEF(0);\n");
708 if (*r == 'n') printf("CDEF(n);\n");
709 if (*r == 'm') printf("CDEF(m);\n");
710
711 }
712
713 }
714 printf ("break;\n");
594266fc
SC
715 printf ("}\n");
716 }
2ca7c3c4 717 printf("default:\n{\nabort();;\n}\n");
594266fc
SC
718 printf ("}\n}\n");
719}
720
721
acae2683
TG
722static void
723gendefines ()
724{
725 op *p;
726 filltable();
727 for (p = tab; p->name; p++)
728 {
729 char *s = p->name;
730 printf ("#define OPC_");
731 while (*s) {
732 if (isupper(*s))
733 *s = tolower(*s);
734 if (isalpha(*s)) printf("%c", *s);
735 if (*s == ' ') printf("_");
736 if (*s == '@') printf("ind_");
737 if (*s == ',') printf("_");
738 s++;
739 }
740 printf(" %d\n",p->index);
741 }
742}
743
594266fc
SC
744int
745main (ac, av)
acae2683 746 int ac;
594266fc 747 char **av;
594266fc
SC
748{
749 if (ac > 1)
750 {
751 if (strcmp (av[1], "-t") == 0)
752 {
753 gengastab ();
754 }
acae2683
TG
755 else if (strcmp (av[1], "-d") == 0)
756 {
757 gendefines ();
758 }
594266fc
SC
759 else if (strcmp (av[1], "-s") == 0)
760 {
761 filltable ();
762 dumptable ();
763
764 }
765 else if (strcmp (av[1], "-x") == 0)
766 {
767 filltable ();
768 gensim ();
769 }
770 }
771 else
772 {
773 genopc ();
774 }
775 return 0;
776}
This page took 0.12609 seconds and 4 git commands to generate.