1 datatype Inst :: rewrite =
2 ADDD(Inst,Inst) | ADDF(Inst,Inst) | ADDI(Inst,Inst)
3 | ADDP(Inst,Inst) | ADDU(Inst,Inst)
4 | ADDRFP() | ADDRGP() | ADDRLP()
5 | ARGB(Inst) | ARGD(Inst) | ARGF(Inst) | ARGI(Inst) | ARGP(Inst)
6 | ASGNB(Inst,Inst) | ASGNC(Inst,Inst) | ASGND(Inst,Inst)
7 | ASGNF(Inst,Inst) | ASGNI(Inst,Inst) | ASGNP(Inst,Inst) | ASGNS(Inst,Inst)
8 | BANDU(Inst,Inst) | BCOMU(Inst) | BORU(Inst,Inst) | BXORU(Inst,Inst)
9 | CALLB(Inst,Inst) | CALLD(Inst) | CALLF(Inst) | CALLI(Inst) | CALLV(Inst)
10 | CNSTC() | CNSTD() | CNSTF() | CNSTI() | CNSTP() | CNSTS() | CNSTU()
11 | CVCI(Inst) | CVCU(Inst) | CVDF(Inst) | CVDI(Inst) | CVFD(Inst)
12 | CVIC(Inst) | CVID(Inst) | CVIS(Inst) | CVIU(Inst) | CVPU(Inst)
13 | CVSI(Inst) | CVSU(Inst)
14 | CVUC(Inst) | CVUI(Inst) | CVUP(Inst) | CVUS(Inst)
15 | DIVD(Inst,Inst) | DIVF(Inst,Inst) | DIVI(Inst,Inst) | DIVU(Inst,Inst)
16 | EQD(Inst,Inst) | EQF(Inst,Inst) | EQI(Inst,Inst)
17 | GED(Inst,Inst) | GEF(Inst,Inst) | GEI(Inst,Inst) | GEU(Inst,Inst)
18 | GTD(Inst,Inst) | GTF(Inst,Inst) | GTI(Inst,Inst) | GTU(Inst,Inst)
19 | INDIRB(Inst) | INDIRC(Inst) | INDIRD(Inst) | INDIRF(Inst)
20 | INDIRI(Inst) | INDIRP(Inst) | INDIRS(Inst)
21 | JUMPV(Inst) | LABELV()
22 | LED(Inst,Inst) | LEF(Inst,Inst) | LEI(Inst,Inst) | LEU(Inst,Inst)
23 | LOADB(Inst) | LOADC(Inst) | LOADD(Inst) | LOADF(Inst)
24 | LOADI(Inst) | LOADP(Inst) | LOADS(Inst) | LOADU(Inst)
25 | LSHI(Inst,Inst) | LSHU(Inst,Inst)
26 | LTD(Inst,Inst) | LTF(Inst,Inst) | LTI(Inst,Inst) | LTU(Inst,Inst)
27 | MODI(Inst,Inst) | MODU(Inst,Inst)
28 | MULD(Inst,Inst) | MULF(Inst,Inst) | MULI(Inst,Inst) | MULU(Inst,Inst)
29 | NED(Inst,Inst) | NEF(Inst,Inst) | NEI(Inst,Inst)
30 | NEGD(Inst) | NEGF(Inst) | NEGI(Inst)
31 | RETD(Inst) | RETF(Inst) | RETI(Inst)
32 | RSHI(Inst,Inst) | RSHU(Inst,Inst)
33 | SUBD(Inst,Inst) | SUBF(Inst,Inst) | SUBI(Inst,Inst)
34 | SUBP(Inst,Inst) | SUBU(Inst,Inst)
38 extern int move(Inst);
39 extern int range(Inst,int,int);
41 extern int notarget(Inst);
45 rewrite (e) type (Inst) :: treeparser of
46 reg -> INDIRC(VREGP()): { "# read register\n"; }
47 | reg -> INDIRD(VREGP()): { "# read register\n"; }
48 | reg -> INDIRF(VREGP()): { "# read register\n"; }
49 | reg -> INDIRI(VREGP()): { "# read register\n"; }
50 | reg -> INDIRP(VREGP()): { "# read register\n"; }
51 | reg -> INDIRS(VREGP()): { "# read register\n"; }
52 | stmt -> ASGNC(VREGP(),reg): { "# write register\n"; }
53 | stmt -> ASGND(VREGP(),reg): { "# write register\n"; }
54 | stmt -> ASGNF(VREGP(),reg): { "# write register\n"; }
55 | stmt -> ASGNI(VREGP(),reg): { "# write register\n"; }
56 | stmt -> ASGNP(VREGP(),reg): { "# write register\n"; }
57 | stmt -> ASGNS(VREGP(),reg): { "# write register\n"; }
58 | con -> CNSTC(): { "%a"; }
59 | con -> CNSTI(): { "%a"; }
60 | con -> CNSTP(): { "%a"; }
61 | con -> CNSTS(): { "%a"; }
62 | con -> CNSTU(): { "%a"; }
63 | stmt -> reg: { ""; }
64 | reg -> CVIU(reg) \ notarget(redex): { "%0"; }
65 | reg -> CVPU(reg) \ notarget(redex): { "%0"; }
66 | reg -> CVUI(reg) \ notarget(redex): { "%0"; }
67 | reg -> CVUP(reg) \ notarget(redex): { "%0"; }
68 | reg -> ADDRGP(): { "set %a,%%%c\n"; }
69 | stk13 -> ADDRFP(): { "%a"; }
70 | stk13 -> ADDRLP(): { "%a"; }
71 | reg -> stk13 \ 1: { "add %0,%%fp,%%%c\n"; }
72 | stk -> ADDRFP() \ 2: { "set %a,%%%c\n"; }
73 | stk -> ADDRLP() \ 2: { "set %a,%%%c\n"; }
74 | reg -> ADDRFP() \ 3: { "set %a,%%%c\nadd %%%c,%%fp,%%%c\n"; }
75 | reg -> ADDRLP() \ 3: { "set %a,%%%c\nadd %%%c,%%fp,%%%c\n"; }
76 | con13 -> CNSTC() \ imm(redex): { "%a"; }
77 | con13 -> CNSTI() \ imm(redex): { "%a"; }
78 | con13 -> CNSTP() \ imm(redex): { "%a"; }
79 | con13 -> CNSTS() \ imm(redex): { "%a"; }
80 | con13 -> CNSTU() \ imm(redex): { "%a"; }
81 | base -> ADDI(reg,con13): { "%%%0+%1"; }
82 | base -> ADDP(reg,con13): { "%%%0+%1"; }
83 | base -> ADDU(reg,con13): { "%%%0+%1"; }
84 | base -> reg: { "%%%0"; }
85 | base -> con13: { "%0"; }
86 | base -> stk13: { "%%fp+%0"; }
87 | addr -> base: { "%0"; }
88 | addr -> ADDI(reg,reg): { "%%%0+%%%1"; }
89 | addr -> ADDP(reg,reg): { "%%%0+%%%1"; }
90 | addr -> ADDU(reg,reg): { "%%%0+%%%1"; }
91 | addr -> stk: { "%%fp+%%%0"; }
92 | reg -> INDIRC(addr) \ 1: { "ldsb [%0],%%%c\n"; }
93 | reg -> INDIRS(addr) \ 1: { "ldsh [%0],%%%c\n"; }
94 | reg -> INDIRI(addr) \ 1: { "ld [%0],%%%c\n"; }
95 | reg -> INDIRP(addr) \ 1: { "ld [%0],%%%c\n"; }
96 | reg -> INDIRF(addr) \ 1: { "ld [%0],%%f%c\n"; }
97 | stmt -> ASGNC(addr,reg) \ 1: { "stb %%%1,[%0]\n"; }
98 | stmt -> ASGNS(addr,reg) \ 1: { "sth %%%1,[%0]\n"; }
99 | stmt -> ASGNI(addr,reg) \ 1: { "st %%%1,[%0]\n"; }
100 | stmt -> ASGNP(addr,reg) \ 1: { "st %%%1,[%0]\n"; }
101 | stmt -> ASGNF(addr,reg) \ 1: { "st %%f%1,[%0]\n"; }
102 | addrl -> ADDRLP() \ imm(redex): { "%%%fp+%a"; }
103 | reg -> INDIRD(addrl) \ 1: { "ldd [%0],%%f%c\n"; }
104 | stmt -> ASGND(addrl,reg) \ 1: { "std %%f%1,[%0]\n"; }
105 | reg -> INDIRD(base) \ 2: { "ld2 [%0],%%f%c\n"; }
106 | stmt -> ASGND(base,reg) \ 2: { "st2 %%f%1,[%0]\n"; }
107 | spill -> ADDRLP() \ ! imm(redex): { "%a"; }
108 | stmt -> ASGNC(spill,reg): { "set %0,%%g1\nstb %%%1,[%%fp+%%g1]\n"; }
109 | stmt -> ASGNS(spill,reg): { "set %0,%%g1\nsth %%%1,[%%fp+%%g1]\n"; }
110 | stmt -> ASGNI(spill,reg): { "set %0,%%g1\nst %%%1,[%%fp+%%g1]\n"; }
111 | stmt -> ASGNP(spill,reg): { "set %0,%%g1\nst %%%1,[%%fp+%%g1]\n"; }
112 | stmt -> ASGNF(spill,reg): { "set %0,%%g1\nst %%f%1,[%%fp+%%g1]\n"; }
113 | stmt -> ASGND(spill,reg): { "set %0,%%g1\nstd %%f%1,[%%fp+%%g1]\n"; }
114 | reg -> CVCI(INDIRC(addr)): { "ldsb [%0],%%%c\n"; }
115 | reg -> CVSI(INDIRS(addr)): { "ldsh [%0],%%%c\n"; }
116 | reg -> CVCU(INDIRC(addr)): { "ldub [%0],%%%c\n"; }
117 | reg -> CVSU(INDIRS(addr)): { "lduh [%0],%%%c\n"; }
118 | reg -> CVIC(reg) \ move(redex): { "mov %%%0,%%%c\n"; }
119 | reg -> CVIS(reg) \ move(redex): { "mov %%%0,%%%c\n"; }
120 | reg -> CVIU(reg) \ move(redex): { "mov %%%0,%%%c\n"; }
121 | reg -> CVPU(reg) \ move(redex): { "mov %%%0,%%%c\n"; }
122 | reg -> CVUC(reg) \ move(redex): { "mov %%%0,%%%c\n"; }
123 | reg -> CVUI(reg) \ move(redex): { "mov %%%0,%%%c\n"; }
124 | reg -> CVUP(reg) \ move(redex): { "mov %%%0,%%%c\n"; }
125 | reg -> CVUS(reg) \ move(redex): { "mov %%%0,%%%c\n"; }
126 | reg -> CVIC(reg) \ notarget(redex): { "%0"; }
127 | reg -> CVIS(reg) \ notarget(redex): { "%0"; }
128 | reg -> CVUC(reg) \ notarget(redex): { "%0"; }
129 | reg -> CVUS(reg) \ notarget(redex): { "%0"; }
130 | reg -> LOADC(reg) \ move(redex): { "mov %%%0,%%%c\n"; }
131 | reg -> LOADI(reg) \ move(redex): { "mov %%%0,%%%c\n"; }
132 | reg -> LOADP(reg) \ move(redex): { "mov %%%0,%%%c\n"; }
133 | reg -> LOADS(reg) \ move(redex): { "mov %%%0,%%%c\n"; }
134 | reg -> LOADU(reg) \ move(redex): { "mov %%%0,%%%c\n"; }
135 | reg -> CNSTC() \ range(redex,0,0): { "# reg\n"; }
136 | reg -> CNSTI() \ range(redex,0,0): { "# reg\n"; }
137 | reg -> CNSTP() \ range(redex,0,0): { "# reg\n"; }
138 | reg -> CNSTS() \ range(redex,0,0): { "# reg\n"; }
139 | reg -> CNSTU() \ range(redex,0,0): { "# reg\n"; }
140 | reg -> con \ 1: { "set %0,%%%c\n"; }
141 | rc -> con13: { "%0"; }
142 | rc -> reg: { "%%%0"; }
143 | reg -> ADDI(reg,rc) \ 1: { "add %%%0,%1,%%%c\n"; }
144 | reg -> ADDP(reg,rc) \ 1: { "add %%%0,%1,%%%c\n"; }
145 | reg -> ADDU(reg,rc) \ 1: { "add %%%0,%1,%%%c\n"; }
146 | reg -> BANDU(reg,rc) \ 1: { "and %%%0,%1,%%%c\n"; }
147 | reg -> BORU(reg,rc) \ 1: { "or %%%0,%1,%%%c\n" ; }
148 | reg -> BXORU(reg,rc) \ 1: { "xor %%%0,%1,%%%c\n"; }
149 | reg -> SUBI(reg,rc) \ 1: { "sub %%%0,%1,%%%c\n"; }
150 | reg -> SUBP(reg,rc) \ 1: { "sub %%%0,%1,%%%c\n"; }
151 | reg -> SUBU(reg,rc) \ 1: { "sub %%%0,%1,%%%c\n"; }
152 | rc5 -> CNSTI() \ range(redex,0,31): { "%a"; }
153 | rc5 -> reg: { "%%%0"; }
154 | reg -> LSHI(reg,rc5) \ 1: { "sll %%%0,%1,%%%c\n"; }
155 | reg -> LSHU(reg,rc5) \ 1: { "sll %%%0,%1,%%%c\n"; }
156 | reg -> RSHI(reg,rc5) \ 1: { "sra %%%0,%1,%%%c\n"; }
157 | reg -> RSHU(reg,rc5) \ 1: { "srl %%%0,%1,%%%c\n"; }
158 | reg -> BANDU(reg,BCOMU(rc)) \ 1: { "andn %%%0,%1,%%%c\n"; }
159 | reg -> BORU(reg,BCOMU(rc)) \ 1: { "orn %%%0,%1,%%%c\n"; }
160 | reg -> BXORU(reg,BCOMU(rc)) \ 1: { "xnor %%%0,%1,%%%c\n"; }
161 | reg -> NEGI(reg) \ 1: { "neg %%%0,%%%c\n"; }
162 | reg -> BCOMU(reg) \ 1: { "not %%%0,%%%c\n"; }
163 | reg -> CVCI(reg) \ 2: { "sll %%%0,24,%%%c; sra %%%c,24,%%%c\n"; }
164 | reg -> CVSI(reg) \ 2: { "sll %%%0,16,%%%c; sra %%%c,16,%%%c\n"; }
165 | reg -> CVCU(reg) \ 1: { "and %%%0,0xff,%%%c\n"; }
166 | reg -> CVSU(reg) \ 2: { "set 0xffff,%%g1; and %%%0,%%g1,%%%c\n"; }
167 | addrg -> ADDRGP(): { "%a"; }
168 | stmt -> JUMPV(addrg) \ 2: { "ba %0; nop\n"; }
169 | stmt -> JUMPV(addr) \ 2: { "jmp %0; nop\n"; }
170 | stmt -> LABELV(): { "%a:\n"; }
171 | stmt -> EQI(reg,rc) \ 3: { "cmp %%%0,%1; be %a; nop\n"; }
172 | stmt -> GEI(reg,rc) \ 3: { "cmp %%%0,%1; bge %a; nop\n"; }
173 | stmt -> GEU(reg,rc) \ 3: { "cmp %%%0,%1; bgeu %a; nop\n"; }
174 | stmt -> GTI(reg,rc) \ 3: { "cmp %%%0,%1; bg %a; nop\n"; }
175 | stmt -> GTU(reg,rc) \ 3: { "cmp %%%0,%1; bgu %a; nop\n"; }
176 | stmt -> LEI(reg,rc) \ 3: { "cmp %%%0,%1; ble %a; nop\n"; }
177 | stmt -> LEU(reg,rc) \ 3: { "cmp %%%0,%1; bleu %a; nop\n"; }
178 | stmt -> LTI(reg,rc) \ 3: { "cmp %%%0,%1; bl %a; nop\n"; }
179 | stmt -> LTU(reg,rc) \ 3: { "cmp %%%0,%1; blu %a; nop\n"; }
180 | stmt -> NEI(reg,rc) \ 3: { "cmp %%%0,%1; bne %a; nop\n"; }
181 | call -> ADDRGP(): { "%a"; }
182 | call -> addr: { "%0"; }
183 | reg -> CALLD(call) \ 2: { "call %0; nop\n"; }
184 | reg -> CALLF(call) \ 2: { "call %0; nop\n"; }
185 | reg -> CALLI(call) \ 2: { "call %0; nop\n"; }
186 | stmt -> CALLV(call) \ 2: { "call %0; nop\n"; }
187 | stmt -> CALLB(call,reg) \ 2: { "call %0; st %%%1,[%%sp+64]\n"; }
188 | stmt -> RETD(reg) \ 1: { "# ret\n"; }
189 | stmt -> RETF(reg) \ 1: { "# ret\n"; }
190 | stmt -> RETI(reg) \ 1: { "# ret\n"; }
191 | stmt -> ARGI(reg) \ 1: { "st %%%0,[%%sp+4*%c+68]\n"; }
192 | stmt -> ARGP(reg) \ 1: { "st %%%0,[%%sp+4*%c+68]\n"; }
193 | stmt -> ARGD(reg) \ 1: { "# ARGD\n"; }
194 | stmt -> ARGF(reg) \ 1: { "# ARGF\n"; }
195 | reg -> DIVI(reg,reg) \ 2: { "call .div,2; nop\n"; }
196 | reg -> DIVU(reg,reg) \ 2: { "call .udiv,2; nop\n"; }
197 | reg -> MODI(reg,reg) \ 2: { "call .rem,2; nop\n"; }
198 | reg -> MODU(reg,reg) \ 2: { "call .urem,2; nop\n"; }
199 | reg -> MULI(reg,reg) \ 2: { "call .mul,2; nop\n"; }
200 | reg -> MULU(reg,reg) \ 2: { "call .umul,2; nop\n"; }
201 | reg -> ADDD(reg,reg) \ 1: { "faddd %%f%0,%%f%1,%%f%c\n"; }
202 | reg -> ADDF(reg,reg) \ 1: { "fadds %%f%0,%%f%1,%%f%c\n"; }
203 | reg -> DIVD(reg,reg) \ 1: { "fdivd %%f%0,%%f%1,%%f%c\n"; }
204 | reg -> DIVF(reg,reg) \ 1: { "fdivs %%f%0,%%f%1,%%f%c\n"; }
205 | reg -> MULD(reg,reg) \ 1: { "fmuld %%f%0,%%f%1,%%f%c\n"; }
206 | reg -> MULF(reg,reg) \ 1: { "fmuls %%f%0,%%f%1,%%f%c\n"; }
207 | reg -> SUBD(reg,reg) \ 1: { "fsubd %%f%0,%%f%1,%%f%c\n"; }
208 | reg -> SUBF(reg,reg) \ 1: { "fsubs %%f%0,%%f%1,%%f%c\n"; }
209 | reg -> NEGF(reg) \ 1: { "fnegs %%f%0,%%f%c\n"; }
210 | reg -> LOADF(reg) \ 1: { "fmovs %%f%0,%%f%c\n"; }
211 | reg -> CVDF(reg) \ 1: { "fdtos %%f%0,%%f%c\n"; }
212 | reg -> CVFD(reg) \ 1: { "fstod %%f%0,%%f%c\n"; }
213 | reg -> CVDI(reg) \ 3: { "fdtoi %%f%0,%%f0; st %%f0,[%%sp+64]; ld [%%sp+64],%%%c\n"; }
214 | reg -> CVID(reg) \ 3: { "st %%%0,[%%sp+64]; ld [%%sp+64],%%f%c; fitod %%f%c,%%f%c\n"; }
215 | rel -> EQD(reg,reg): { "fcmped %%f%0,%%f%1; nop; fbue"; }
216 | rel -> EQF(reg,reg): { "fcmpes %%f%0,%%f%1; nop; fbue"; }
217 | rel -> GED(reg,reg): { "fcmped %%f%0,%%f%1; nop; fbuge"; }
218 | rel -> GEF(reg,reg): { "fcmpes %%f%0,%%f%1; nop; fbuge"; }
219 | rel -> GTD(reg,reg): { "fcmped %%f%0,%%f%1; nop; fbug"; }
220 | rel -> GTF(reg,reg): { "fcmpes %%f%0,%%f%1; nop; fbug"; }
221 | rel -> LED(reg,reg): { "fcmped %%f%0,%%f%1; nop; fbule"; }
222 | rel -> LEF(reg,reg): { "fcmpes %%f%0,%%f%1; nop; fbule"; }
223 | rel -> LTD(reg,reg): { "fcmped %%f%0,%%f%1; nop; fbul"; }
224 | rel -> LTF(reg,reg): { "fcmpes %%f%0,%%f%1; nop; fbul"; }
225 | rel -> NED(reg,reg): { "fcmped %%f%0,%%f%1; nop; fbne"; }
226 | rel -> NEF(reg,reg): { "fcmpes %%f%0,%%f%1; nop; fbne"; }
227 | stmt -> rel \ 4: { "%0 %a; nop\n"; }
228 | reg -> LOADD(reg) \ 2: { "# LOADD\n"; }
229 | reg -> NEGD(reg) \ 2: { "# NEGD\n"; }
230 | stmt -> ASGNB(reg,INDIRB(reg)): { "# ASGNB\n"; }