gcc config
[prop.git] / prop-src / sparc.md
blob80a0f200e8e03096fd3d4c2afc072463245730f2
1 %{
2 #include "c.h"
3 #define NODEPTR_TYPE Node
4 #define OP_LABEL(p) ((p)->op)
5 #define LEFT_CHILD(p) ((p)->kids[0])
6 #define RIGHT_CHILD(p) ((p)->kids[1])
7 #define STATE_LABEL(p) ((p)->x.state)
8 static void address     ARGS((Symbol, Symbol, int));
9 static void blkfetch    ARGS((int, int, int, int));
10 static void blkloop     ARGS((int, int, int, int, int, int[]));
11 static void blkstore    ARGS((int, int, int, int));
12 static void defaddress  ARGS((Symbol));
13 static void defconst    ARGS((int, Value));
14 static void defstring   ARGS((int, char *));
15 static void defsymbol   ARGS((Symbol));
16 static void doarg       ARGS((Node));
17 static void emit2       ARGS((Node));
18 static void export      ARGS((Symbol));
19 static void clobber     ARGS((Node));
20 static void function    ARGS((Symbol, Symbol [], Symbol [], int));
21 static void global      ARGS((Symbol));
22 static void import      ARGS((Symbol));
23 static void local       ARGS((Symbol));
24 static void progbeg     ARGS((int, char **));
25 static void progend     ARGS((void));
26 static void segment     ARGS((int));
27 static void space       ARGS((int));
28 static void target      ARGS((Node));
29 static int imm ARGS((Node));
30 static void rename ARGS((void));
31 static void defsymbol2 ARGS((Symbol));
32 static void global2 ARGS((Symbol));
33 static void segment2 ARGS((int));
35 static Symbol greg[32];
36 static Symbol *oreg = &greg[8], *ireg = &greg[24];
37 static Symbol freg[32], freg2[32];
39 static int retstruct;
41 static int pflag = 0;
43 static int cseg;
46 %start stmt
47 %term ADDD=306 ADDF=305 ADDI=309 ADDP=311 ADDU=310
48 %term ADDRFP=279
49 %term ADDRGP=263
50 %term ADDRLP=295
51 %term ARGB=41 ARGD=34 ARGF=33 ARGI=37 ARGP=39
52 %term ASGNB=57 ASGNC=51 ASGND=50 ASGNF=49 ASGNI=53 ASGNP=55 ASGNS=52
53 %term BANDU=390
54 %term BCOMU=406
55 %term BORU=422
56 %term BXORU=438
57 %term CALLB=217 CALLD=210 CALLF=209 CALLI=213 CALLV=216
58 %term CNSTC=19 CNSTD=18 CNSTF=17 CNSTI=21 CNSTP=23 CNSTS=20 CNSTU=22
59 %term CVCI=85 CVCU=86
60 %term CVDF=97 CVDI=101
61 %term CVFD=114
62 %term CVIC=131 CVID=130 CVIS=132 CVIU=134
63 %term CVPU=150
64 %term CVSI=165 CVSU=166
65 %term CVUC=179 CVUI=181 CVUP=183 CVUS=180
66 %term DIVD=450 DIVF=449 DIVI=453 DIVU=454
67 %term EQD=482 EQF=481 EQI=485
68 %term GED=498 GEF=497 GEI=501 GEU=502
69 %term GTD=514 GTF=513 GTI=517 GTU=518
70 %term INDIRB=73 INDIRC=67 INDIRD=66 INDIRF=65 INDIRI=69 INDIRP=71 INDIRS=68
71 %term JUMPV=584
72 %term LABELV=600
73 %term LED=530 LEF=529 LEI=533 LEU=534
74 %term LOADB=233 LOADC=227 LOADD=226 LOADF=225 LOADI=229 LOADP=231 LOADS=228 LOADU=230
75 %term LSHI=341 LSHU=342
76 %term LTD=546 LTF=545 LTI=549 LTU=550
77 %term MODI=357 MODU=358
78 %term MULD=466 MULF=465 MULI=469 MULU=470
79 %term NED=562 NEF=561 NEI=565
80 %term NEGD=194 NEGF=193 NEGI=197
81 %term RETD=242 RETF=241 RETI=245
82 %term RSHI=373 RSHU=374
83 %term SUBD=322 SUBF=321 SUBI=325 SUBP=327 SUBU=326
84 %term VREGP=615
86 reg:  INDIRC(VREGP)     "# read register\n"
87 reg:  INDIRD(VREGP)     "# read register\n"
88 reg:  INDIRF(VREGP)     "# read register\n"
89 reg:  INDIRI(VREGP)     "# read register\n"
90 reg:  INDIRP(VREGP)     "# read register\n"
91 reg:  INDIRS(VREGP)     "# read register\n"
92 stmt: ASGNC(VREGP,reg)  "# write register\n"
93 stmt: ASGND(VREGP,reg)  "# write register\n"
94 stmt: ASGNF(VREGP,reg)  "# write register\n"
95 stmt: ASGNI(VREGP,reg)  "# write register\n"
96 stmt: ASGNP(VREGP,reg)  "# write register\n"
97 stmt: ASGNS(VREGP,reg)  "# write register\n"
98 con: CNSTC  "%a"
99 con: CNSTI  "%a"
100 con: CNSTP  "%a"
101 con: CNSTS  "%a"
102 con: CNSTU  "%a"
103 stmt: reg  ""
104 reg: CVIU(reg)  "%0"  notarget(a)
105 reg: CVPU(reg)  "%0"  notarget(a)
106 reg: CVUI(reg)  "%0"  notarget(a)
107 reg: CVUP(reg)  "%0"  notarget(a)
108 reg: ADDRGP  "set %a,%%%c\n"  1
109 stk13: ADDRFP  "%a"                  imm(a)
110 stk13: ADDRLP  "%a"                  imm(a)
111 reg:   stk13   "add %0,%%fp,%%%c\n"  1
112 stk: ADDRFP  "set %a,%%%c\n"                      2
113 stk: ADDRLP  "set %a,%%%c\n"                      2
114 reg: ADDRFP  "set %a,%%%c\nadd %%%c,%%fp,%%%c\n"  3
115 reg: ADDRLP  "set %a,%%%c\nadd %%%c,%%fp,%%%c\n"  3
116 con13: CNSTC  "%a"  imm(a)
117 con13: CNSTI  "%a"  imm(a)
118 con13: CNSTP  "%a"  imm(a)
119 con13: CNSTS  "%a"  imm(a)
120 con13: CNSTU  "%a"  imm(a)
121 base: ADDI(reg,con13)  "%%%0+%1"
122 base: ADDP(reg,con13)  "%%%0+%1"
123 base: ADDU(reg,con13)  "%%%0+%1"
124 base: reg    "%%%0"
125 base: con13  "%0"
126 base: stk13  "%%fp+%0"
127 addr: base           "%0"
128 addr: ADDI(reg,reg)  "%%%0+%%%1"
129 addr: ADDP(reg,reg)  "%%%0+%%%1"
130 addr: ADDU(reg,reg)  "%%%0+%%%1"
131 addr: stk            "%%fp+%%%0"
132 reg:  INDIRC(addr)     "ldsb [%0],%%%c\n"  1
133 reg:  INDIRS(addr)     "ldsh [%0],%%%c\n"  1
134 reg:  INDIRI(addr)     "ld [%0],%%%c\n"    1
135 reg:  INDIRP(addr)     "ld [%0],%%%c\n"    1
136 reg:  INDIRF(addr)     "ld [%0],%%f%c\n"   1
137 stmt: ASGNC(addr,reg)  "stb %%%1,[%0]\n"   1
138 stmt: ASGNS(addr,reg)  "sth %%%1,[%0]\n"   1
139 stmt: ASGNI(addr,reg)  "st %%%1,[%0]\n"    1
140 stmt: ASGNP(addr,reg)  "st %%%1,[%0]\n"    1
141 stmt: ASGNF(addr,reg)  "st %%f%1,[%0]\n"   1
142 addrl: ADDRLP            "%%%fp+%a"          imm(a)
144 reg:   INDIRD(addrl)     "ldd [%0],%%f%c\n"  1
145 stmt:  ASGND(addrl,reg)  "std %%f%1,[%0]\n"  1
146 reg:  INDIRD(base)     "ld2 [%0],%%f%c\n"  2
147 stmt: ASGND(base,reg)  "st2 %%f%1,[%0]\n"  2
148 spill:  ADDRLP          "%a" !imm(a)
150 stmt: ASGNC(spill,reg)  "set %0,%%g1\nstb %%%1,[%%fp+%%g1]\n"
151 stmt: ASGNS(spill,reg)  "set %0,%%g1\nsth %%%1,[%%fp+%%g1]\n"
152 stmt: ASGNI(spill,reg)  "set %0,%%g1\nst %%%1,[%%fp+%%g1]\n"
153 stmt: ASGNP(spill,reg)  "set %0,%%g1\nst %%%1,[%%fp+%%g1]\n"
154 stmt: ASGNF(spill,reg)  "set %0,%%g1\nst %%f%1,[%%fp+%%g1]\n"
155 stmt: ASGND(spill,reg)  "set %0,%%g1\nstd %%f%1,[%%fp+%%g1]\n"
156 reg: CVCI(INDIRC(addr))  "ldsb [%0],%%%c\n"  1
157 reg: CVSI(INDIRS(addr))  "ldsh [%0],%%%c\n"  1
158 reg: CVCU(INDIRC(addr))  "ldub [%0],%%%c\n"  1
159 reg: CVSU(INDIRS(addr))  "lduh [%0],%%%c\n"  1
160 reg: CVIC(reg)  "mov %%%0,%%%c\n"  move(a)
161 reg: CVIS(reg)  "mov %%%0,%%%c\n"  move(a)
162 reg: CVIU(reg)  "mov %%%0,%%%c\n"  move(a)
163 reg: CVPU(reg)  "mov %%%0,%%%c\n"  move(a)
164 reg: CVUC(reg)  "mov %%%0,%%%c\n"  move(a)
165 reg: CVUI(reg)  "mov %%%0,%%%c\n"  move(a)
166 reg: CVUP(reg)  "mov %%%0,%%%c\n"  move(a)
167 reg: CVUS(reg)  "mov %%%0,%%%c\n"  move(a)
168 reg: CVIC(reg)  "%0"  notarget(a)
169 reg: CVIS(reg)  "%0"  notarget(a)
170 reg: CVUC(reg)  "%0"  notarget(a)
171 reg: CVUS(reg)  "%0"  notarget(a)
172 reg: LOADC(reg)  "mov %%%0,%%%c\n"  move(a)
173 reg: LOADI(reg)  "mov %%%0,%%%c\n"  move(a)
174 reg: LOADP(reg)  "mov %%%0,%%%c\n"  move(a)
175 reg: LOADS(reg)  "mov %%%0,%%%c\n"  move(a)
176 reg: LOADU(reg)  "mov %%%0,%%%c\n"  move(a)
177 reg: CNSTC  "# reg\n"  range(a, 0, 0)
178 reg: CNSTI  "# reg\n"  range(a, 0, 0)
179 reg: CNSTP  "# reg\n"  range(a, 0, 0)
180 reg: CNSTS  "# reg\n"  range(a, 0, 0)
181 reg: CNSTU  "# reg\n"  range(a, 0, 0)
182 reg: con  "set %0,%%%c\n"  1
183 rc: con13  "%0"
184 rc: reg    "%%%0"
185 reg: ADDI(reg,rc)   "add %%%0,%1,%%%c\n"  1
186 reg: ADDP(reg,rc)   "add %%%0,%1,%%%c\n"  1
187 reg: ADDU(reg,rc)   "add %%%0,%1,%%%c\n"  1
188 reg: BANDU(reg,rc)  "and %%%0,%1,%%%c\n"  1
189 reg: BORU(reg,rc)   "or %%%0,%1,%%%c\n"   1
190 reg: BXORU(reg,rc)  "xor %%%0,%1,%%%c\n"  1
191 reg: SUBI(reg,rc)   "sub %%%0,%1,%%%c\n"  1
192 reg: SUBP(reg,rc)   "sub %%%0,%1,%%%c\n"  1
193 reg: SUBU(reg,rc)   "sub %%%0,%1,%%%c\n"  1
194 rc5: CNSTI  "%a"    range(a, 0, 31)
195 rc5: reg    "%%%0"
196 reg: LSHI(reg,rc5)  "sll %%%0,%1,%%%c\n"  1
197 reg: LSHU(reg,rc5)  "sll %%%0,%1,%%%c\n"  1
198 reg: RSHI(reg,rc5)  "sra %%%0,%1,%%%c\n"  1
199 reg: RSHU(reg,rc5)  "srl %%%0,%1,%%%c\n"  1
200 reg: BANDU(reg,BCOMU(rc))  "andn %%%0,%1,%%%c\n"  1
201 reg: BORU(reg,BCOMU(rc))   "orn %%%0,%1,%%%c\n"   1
202 reg: BXORU(reg,BCOMU(rc))  "xnor %%%0,%1,%%%c\n"  1
203 reg: NEGI(reg)   "neg %%%0,%%%c\n"  1
204 reg: BCOMU(reg)  "not %%%0,%%%c\n"  1
205 reg: CVCI(reg)  "sll %%%0,24,%%%c; sra %%%c,24,%%%c\n"  2
206 reg: CVSI(reg)  "sll %%%0,16,%%%c; sra %%%c,16,%%%c\n"  2
207 reg: CVCU(reg)  "and %%%0,0xff,%%%c\n"                   1
208 reg: CVSU(reg)  "set 0xffff,%%g1; and %%%0,%%g1,%%%c\n"  2
209 addrg: ADDRGP        "%a"
210 stmt:  JUMPV(addrg)  "ba %0; nop\n"   2
211 stmt:  JUMPV(addr)   "jmp %0; nop\n"  2
212 stmt:  LABELV        "%a:\n"
213 stmt: EQI(reg,rc)  "cmp %%%0,%1; be %a; nop\n"    3
214 stmt: GEI(reg,rc)  "cmp %%%0,%1; bge %a; nop\n"   3
215 stmt: GEU(reg,rc)  "cmp %%%0,%1; bgeu %a; nop\n"  3
216 stmt: GTI(reg,rc)  "cmp %%%0,%1; bg %a; nop\n"    3
217 stmt: GTU(reg,rc)  "cmp %%%0,%1; bgu %a; nop\n"   3
218 stmt: LEI(reg,rc)  "cmp %%%0,%1; ble %a; nop\n"   3
219 stmt: LEU(reg,rc)  "cmp %%%0,%1; bleu %a; nop\n"  3
220 stmt: LTI(reg,rc)  "cmp %%%0,%1; bl %a; nop\n"    3
221 stmt: LTU(reg,rc)  "cmp %%%0,%1; blu %a; nop\n"   3
222 stmt: NEI(reg,rc)  "cmp %%%0,%1; bne %a; nop\n"   3
223 call: ADDRGP           "%a"
224 call: addr             "%0"
225 reg:  CALLD(call)      "call %0; nop\n"                2
226 reg:  CALLF(call)      "call %0; nop\n"                2
227 reg:  CALLI(call)      "call %0; nop\n"                2
228 stmt: CALLV(call)      "call %0; nop\n"                2
229 stmt: CALLB(call,reg)  "call %0; st %%%1,[%%sp+64]\n"  2
230 stmt: RETD(reg)  "# ret\n"  1
231 stmt: RETF(reg)  "# ret\n"  1
232 stmt: RETI(reg)  "# ret\n"  1
233 stmt: ARGI(reg)  "st %%%0,[%%sp+4*%c+68]\n"  1
234 stmt: ARGP(reg)  "st %%%0,[%%sp+4*%c+68]\n"  1
235 stmt: ARGD(reg)  "# ARGD\n"  1
236 stmt: ARGF(reg)  "# ARGF\n"  1
238 reg: DIVI(reg,reg)  "call .div,2; nop\n"   2
239 reg: DIVU(reg,reg)  "call .udiv,2; nop\n"  2
240 reg: MODI(reg,reg)  "call .rem,2; nop\n"   2
241 reg: MODU(reg,reg)  "call .urem,2; nop\n"  2
242 reg: MULI(reg,reg)  "call .mul,2; nop\n"   2
243 reg: MULU(reg,reg)  "call .umul,2; nop\n"  2
244 reg: ADDD(reg,reg)  "faddd %%f%0,%%f%1,%%f%c\n"  1
245 reg: ADDF(reg,reg)  "fadds %%f%0,%%f%1,%%f%c\n"  1
246 reg: DIVD(reg,reg)  "fdivd %%f%0,%%f%1,%%f%c\n"  1
247 reg: DIVF(reg,reg)  "fdivs %%f%0,%%f%1,%%f%c\n"  1
248 reg: MULD(reg,reg)  "fmuld %%f%0,%%f%1,%%f%c\n"  1
249 reg: MULF(reg,reg)  "fmuls %%f%0,%%f%1,%%f%c\n"  1
250 reg: SUBD(reg,reg)  "fsubd %%f%0,%%f%1,%%f%c\n"  1
251 reg: SUBF(reg,reg)  "fsubs %%f%0,%%f%1,%%f%c\n"  1
252 reg: NEGF(reg)   "fnegs %%f%0,%%f%c\n"  1
253 reg: LOADF(reg)  "fmovs %%f%0,%%f%c\n"  1
254 reg: CVDF(reg)   "fdtos %%f%0,%%f%c\n"  1
255 reg: CVFD(reg)   "fstod %%f%0,%%f%c\n"  1
256 reg: CVDI(reg)  "fdtoi %%f%0,%%f0; st %%f0,[%%sp+64]; ld [%%sp+64],%%%c\n"  3
258 reg: CVID(reg)  "st %%%0,[%%sp+64]; ld [%%sp+64],%%f%c; fitod %%f%c,%%f%c\n"  3
260 rel: EQD(reg,reg)  "fcmped %%f%0,%%f%1; nop; fbue"
261 rel: EQF(reg,reg)  "fcmpes %%f%0,%%f%1; nop; fbue"
262 rel: GED(reg,reg)  "fcmped %%f%0,%%f%1; nop; fbuge"
263 rel: GEF(reg,reg)  "fcmpes %%f%0,%%f%1; nop; fbuge"
264 rel: GTD(reg,reg)  "fcmped %%f%0,%%f%1; nop; fbug"
265 rel: GTF(reg,reg)  "fcmpes %%f%0,%%f%1; nop; fbug"
266 rel: LED(reg,reg)  "fcmped %%f%0,%%f%1; nop; fbule"
267 rel: LEF(reg,reg)  "fcmpes %%f%0,%%f%1; nop; fbule"
268 rel: LTD(reg,reg)  "fcmped %%f%0,%%f%1; nop; fbul"
269 rel: LTF(reg,reg)  "fcmpes %%f%0,%%f%1; nop; fbul"
270 rel: NED(reg,reg)  "fcmped %%f%0,%%f%1; nop; fbne"
271 rel: NEF(reg,reg)  "fcmpes %%f%0,%%f%1; nop; fbne"
273 stmt: rel  "%0 %a; nop\n"  4
274 reg:  LOADD(reg)  "# LOADD\n"  2
276 reg:  NEGD(reg)  "# NEGD\n"  2
278 stmt:  ASGNB(reg,INDIRB(reg))  "# ASGNB\n"
281 static void progend(){}
282 static void progbeg(argc, argv) int argc; char *argv[]; {
283         int i;
285         {
286                 union {
287                         char c;
288                         int i;
289                 } u;
290                 u.i = 0;
291                 u.c = 1;
292                 swap = (u.i == 1) != IR->little_endian;
293         }
294         parseflags(argc, argv);
295         for (i = 0; i < argc; i++)
296                 if (strcmp(argv[i], "-p") == 0 || strcmp(argv[i], "-pg") == 0)
297                         pflag = 1;
298         for (i = 0; i < 8; i++) {
299                 greg[i +  0] = mkreg(stringf("g%d", i), i +  0, 1, IREG);
300                 greg[i +  8] = mkreg(stringf("o%d", i), i +  8, 1, IREG);
301                 greg[i + 16] = mkreg(stringf("l%d", i), i + 16, 1, IREG);
302                 greg[i + 24] = mkreg(stringf("i%d", i), i + 24, 1, IREG);
303         }
304         for (i = 0; i < 32; i++)
305                 freg[i]  = mkreg("%d", i, 1, FREG);
306         for (i = 0; i < 31; i += 2)
307                 freg2[i] = mkreg("%d", i, 3, FREG);
308         rmap[C] = rmap[S] = rmap[P] = rmap[B] = rmap[U] = rmap[I] =
309                 mkwildcard(greg);
310         rmap[F] = mkwildcard(freg);
311         rmap[D] = mkwildcard(freg2);
312         tmask[IREG] = 0x3fff3e00;
313         vmask[IREG] = 0x3ff00000;
314         tmask[FREG]  = ~(unsigned)0;
315         vmask[FREG]  = 0;
317 static void target(p) Node p; {
318         assert(p);
319         switch (p->op) {
320         case CNSTC: case CNSTI: case CNSTS: case CNSTU: case CNSTP:
321                 if (range(p, 0, 0) == 0) {
322                         setreg(p, greg[0]);
323                         p->x.registered = 1;
324                 }
325                 break;
326         case CALLD: setreg(p, freg2[0]);     break;
327         case CALLF: setreg(p, freg[0]);      break;
328         case CALLI:
329         case CALLV: setreg(p, oreg[0]);      break;
330         case RETD:  rtarget(p, 0, freg2[0]); break;
331         case RETF:  rtarget(p, 0, freg[0]);  break;
332         case RETI:
333                 rtarget(p, 0, ireg[0]);
334                 p->kids[0]->x.registered = 1;
335                 break;
336         case ARGI: case ARGP:
337                 if (p->syms[RX]->u.c.v.i < 6) {
338                         rtarget(p, 0, oreg[p->syms[RX]->u.c.v.i]);
339                         p->op = LOAD+optype(p->op);
340                         setreg(p, oreg[p->syms[RX]->u.c.v.i]);
341                 }
342                 break;
343         case DIVI: case MODI: case MULI:
344         case DIVU: case MODU: case MULU:
345                 setreg(p, oreg[0]);
346                 rtarget(p, 0, oreg[0]);
347                 rtarget(p, 1, oreg[1]);
348                 break;
349         }
351 static void clobber(p) Node p; {
352         assert(p);
353         switch (p->op) {
354         case CALLB: case CALLD: case CALLF: case CALLI:
355                 spill(~(unsigned)3, FREG, p);
356                 break;
357         case CALLV:
358                 spill(oreg[0]->x.regnode->mask, IREG, p);
359                 spill(~(unsigned)3, FREG, p);
360                 break;
361         case ARGF:
362                 if (p->syms[2]->u.c.v.i <= 6)
363                         spill((1<<(p->syms[2]->u.c.v.i + 8)), IREG, p);
364                 break;
365         case ARGD:
366                 if (p->syms[2]->u.c.v.i <= 5)
367                         spill((3<<(p->syms[2]->u.c.v.i + 8))&0xff00, IREG, p);
368                 break;
369         case DIVI: case MODI: case MULI:
370         case DIVU: case MODU: case MULU:
371                 spill(0x00003e00, IREG, p); break;
372         }
374 static int imm(p) Node p; {
375         return range(p, -4096, 4095);
377 static void doarg(p) Node p; {
378         assert(p && p->syms[0] && p->op != ARG+B);
379         p->syms[RX] = intconst(mkactual(4,
380                 p->syms[0]->u.c.v.i)/4);
382 static void emit2(p) Node p; {
383         switch (p->op) {
384         case ARGF: {
385                 int n = p->syms[RX]->u.c.v.i;
386                 print("st %%f%d,[%%sp+4*%d+68]\n",
387                         getregnum(p->x.kids[0]), n);
388                 if (n <= 5)
389                         print("ld [%%sp+4*%d+68],%%o%d\n", n, n);
390                 break;
391         }
392         case ARGD: {
393                 int n = p->syms[RX]->u.c.v.i;
394                 int src = getregnum(p->x.kids[0]);
395                 print("st %%f%d,[%%sp+4*%d+68]\n", src, n);
396                 print("st %%f%d,[%%sp+4*%d+68]\n", src+1, n+1);
397                 if (n <= 5)
398                         print("ld [%%sp+4*%d+68],%%o%d\n", n, n);
399                 if (n <= 4)
400                         print("ld [%%sp+4*%d+68],%%o%d\n", n+1, n+1);
401                 break;
402         }
403         case LOADD: {
404                 int dst = getregnum(p);
405                 int src = getregnum(p->x.kids[0]);
406                 print("fmovs %%f%d,%%f%d; ", src,   dst);
407                 print("fmovs %%f%d,%%f%d\n", src+1, dst+1);
408                 break;
409         }
410         case NEGD: {
411                 int dst = getregnum(p);
412                 int src = getregnum(p->x.kids[0]);
413                 print("fnegs %%f%d,%%f%d; ", src,   dst);
414                 print("fmovs %%f%d,%%f%d\n", src+1, dst+1);
415                 break;
416         }
417         case ASGNB: {
418                 static int tmpregs[] = { 1, 2, 3 };
419                 dalign = salign = p->syms[1]->u.c.v.i;
420                 blkcopy(getregnum(p->x.kids[0]), 0,
421                         getregnum(p->x.kids[1]), 0,
422                         p->syms[0]->u.c.v.i, tmpregs);
423                 break;
424         }
425         }
427 static void local(p) Symbol p; {
428         if (retstruct) {
429                 p->x.name = stringd(4*16);
430                 p->x.offset = 4*16;
431                 retstruct = 0;
432                 return;
433         }
434         if (isscalar(p->type) && !p->addressed && !isfloat(p->type))
435                 p->sclass = REGISTER;
436         if (glevel && glevel != 3) p->sclass = AUTO;    /* glevel!=3 is for Norman's debugger */
437         if (askregvar(p, rmap[ttob(p->type)]) == 0)
438                 mkauto(p);
440 static void function(f, caller, callee, ncalls)
441 Symbol f, callee[], caller[]; int ncalls; {
442         int autos = 0, i, leaf, reg, varargs;
444         for (i = 0; callee[i]; i++)
445                 ;
446         varargs = variadic(f->type)
447                 || i > 0 && strcmp(callee[i-1]->name,
448                         "__builtin_va_alist") == 0;
449 usedmask[0] = usedmask[1] = 0;
450 freemask[0] = freemask[1] = ~(unsigned)0;
451         for (i = 0; i < 8; i++)
452                 ireg[i]->x.regnode->vbl = NULL;
453         offset = 68;
454         maxargoffset = 24;
455         reg = 0;
456         for (i = 0; callee[i]; i++) {
457                 Symbol p = callee[i], q = caller[i];
458                 int size = roundup(q->type->size, 4);
459                 assert(q);
460                 if (isfloat(p->type) || reg >= 6) {
461                         p->x.offset = q->x.offset = offset;
462                         p->x.name = q->x.name = stringd(offset);
463                         p->sclass = q->sclass = AUTO;
464                         autos++;
465                 }
466                 else if (p->addressed || varargs)
467                         {
468                                 p->x.offset = offset;
469                                 p->x.name = stringd(p->x.offset);
470                                 p->sclass = AUTO;
471                                 q->sclass = REGISTER;
472                                 askregvar(q, ireg[reg]);
473                                 assert(q->x.regnode);
474                                 autos++;
475                         }
476                 else if (glevel && glevel != 3) {
477                                                         p->x.offset = offset;
478                                                         p->x.name = stringd(p->x.offset);
479                                                         p->sclass = AUTO;
480                                                         q->sclass = REGISTER;
481                                                         askregvar(q, ireg[reg]);
482                                                         assert(q->x.regnode);
483                                                         autos++;
484                                                 }
486                 else {
487                         p->sclass = q->sclass = REGISTER;
488                         askregvar(p, ireg[reg]);
489                         assert(p->x.regnode);
490                         q->x.name = p->x.name;
491                 }
492                 offset += size;
493                 reg += isstruct(p->type) ? 1 : size/4;
494         }
495         assert(caller[i] == 0);
496         offset = maxoffset = 0;
497         retstruct = isstruct(freturn(f->type));
498         gencode(caller, callee);
499         maxargoffset = roundup(maxargoffset, 4);
500         framesize = roundup(maxoffset + maxargoffset + 4*(16+1), 8);
501         assert(!varargs || autos);
502         leaf = (!ncalls
503                 && !maxoffset && !autos
504                 && !isstruct(freturn(f->type))
505                 && !(usedmask[IREG]&0x00ffff01)
506                 && !(usedmask[FREG]&~(unsigned)3)
507                 && !pflag && !glevel);
508         print(".align 4\n.proc 4\n%s:\n", f->x.name);
509         if (leaf) {
510                 for (i = 0; caller[i] && callee[i]; i++) {
511                         Symbol p = caller[i], q = callee[i];
512                         if (p->sclass == REGISTER && q->sclass == REGISTER)
513                                 assert(q->x.regnode),
514                                 assert(q->x.regnode->set == IREG),
515                                 assert(q->x.regnode->number >= 24),
516                                 assert(q->x.regnode->number <= 31),
517                                 p->x.name = greg[q->x.regnode->number - 16]->x.name;
518                         }
519                 rename();
520         } else if (framesize <= 4095)
521                 print("save %%sp,%d,%%sp\n", -framesize);
522         else
523                 print("set %d,%%g1; save %%sp,%%g1,%%sp\n", -framesize);
524         if (varargs)
525                 for (; reg < 6; reg++)
526                         print("st %%i%d,[%%fp+%d]\n", reg, 4*reg + 68);
527         else
528                 offset = 4*(16 + 1);
529                 reg = 0;
530                 for (i = 0; caller[i]; i++) {
531                         Symbol p = caller[i];
532                         if (isdouble(p->type) && reg <= 4) {
533                                 print("st %%r%d,[%%fp+%d]\n",
534                                         ireg[reg++]->x.regnode->number, offset);
535                                 print("st %%r%d,[%%fp+%d]\n",
536                                         ireg[reg++]->x.regnode->number, offset + 4);
537                         } else if (isfloat(p->type) && reg <= 5)
538                                 print("st %%r%d,[%%fp+%d]\n",
539                                         ireg[reg++]->x.regnode->number, offset);
540                         else
541                                 reg++;
542                         offset += roundup(p->type->size, 4);
543                 }
544 if (pflag) {
545         int lab = genlabel(1);
546         print("set L%d,%%o0; call mcount; nop\n", lab);
547         print(".seg \"data\"\n.align 4; L%d:.word 0\n.seg \"text\"\n", lab);
549         emitcode();
550         if (!leaf)
551                 print("ret; restore\n");
552         else {
553                 rename();
554                 print("retl; nop\n");
555         }
557 #define exch(x, y, t) (((t) = x), ((x) = (y)), ((y) = (t)))
559 static void rename() {
560         int i;
562         for (i = 0; i < 8; i++) {
563                 char *ptmp;
564                 int itmp;
565                 if (ireg[i]->x.regnode->vbl)
566                         ireg[i]->x.regnode->vbl->x.name = oreg[i]->x.name;
567                 exch(ireg[i]->x.name, oreg[i]->x.name, ptmp);
568                 exch(ireg[i]->x.regnode->number,
569                         oreg[i]->x.regnode->number, itmp);
570         }
572 static void defconst(ty, v) int ty; Value v; {
573         switch (ty) {
574         case C: print(".byte %d\n",   v.uc); return;
575         case S: print(".half %d\n",   v.ss); return;
576         case I: print(".word %d\n",   v.i ); return;
577         case U: print(".word 0x%x\n", v.u ); return;
578         case P: print(".word 0x%x\n", v.p ); return;
579         case F:
580                 print(".word 0x%x\n", *(unsigned *)&v.f);
581                 return;
582 case D: {
583         unsigned *p = (unsigned *)&v.d;
584         print(".word 0x%x\n.word 0x%x\n", p[swap], p[!swap]);
585         return;
586         }
587         }
588         assert(0);
591 static void defaddress(p) Symbol p; {
592         print(".word %s\n", p->x.name);
595 static void defstring(n, str) int n; char *str; {
596         char *s;
598         for (s = str; s < str + n; s++)
599                 print(".byte %d\n", (*s)&0377);
602 static void address(q, p, n) Symbol q, p; int n; {
603         q->x.offset = p->x.offset + n;
604         if (p->scope == GLOBAL || p->sclass == STATIC || p->sclass == EXTERN)
605                 q->x.name = stringf("%s%s%d", p->x.name, n >= 0 ? "+" : "", n);
606         else
607                 q->x.name = stringd(q->x.offset);
609 static void export(p) Symbol p; {
610         print(".global %s\n", p->x.name);
612 static void import(p) Symbol p; {}
613 static void defsymbol(p) Symbol p; {
614         if (p->scope >= LOCAL && p->sclass == STATIC)
615                 p->x.name = stringf("%d", genlabel(1));
616         else
617                 assert(p->scope != CONSTANTS || isint(p->type) || isptr(p->type)),
618                 p->x.name = p->name;
619         if (p->scope >= LABELS)
620                 p->x.name = stringf(p->generated ? "L%s" : "_%s",
621                         p->x.name);
623 static void segment(n) int n; {
624         cseg = n;
625         switch (n) {
626         case CODE: print(".seg \"text\"\n"); break;
627         case BSS:  print(".seg \"bss\"\n");  break;
628         case DATA: print(".seg \"data\"\n"); break;
629         case LIT:  print(".seg \"text\"\n"); break;
630         }
632 static void space(n) int n; {
633         if (cseg != BSS)
634                 print(".skip %d\n", n);
636 static void global(p) Symbol p; {
637         print(".align %d\n", p->type->align);
638         assert(p->u.seg);
639         if (p->u.seg == BSS
640         && (p->sclass == STATIC || Aflag >= 2))
641                 print(".reserve %s,%d\n", p->x.name, p->type->size);
642         else if (p->u.seg == BSS)
643                 print(".common %s,%d\n",  p->x.name, p->type->size);
644         else
645                 print("%s:\n", p->x.name);
647 static void blkfetch(k, off, reg, tmp)
648 int k, off, reg, tmp; {
649         assert(k == 1 || k == 2 || k == 4);
650         assert(salign >= k);
651         if (k == 1)
652                 print("ldub [%%r%d+%d],%%r%d\n", reg, off, tmp);
653         else if (k == 2)
654                 print("lduh [%%r%d+%d],%%r%d\n", reg, off, tmp);
655         else
656                 print("ld [%%r%d+%d],%%r%d\n",   reg, off, tmp);
658 static void blkstore(k, off, reg, tmp)
659 int k, off, reg, tmp; {
660         assert(k == 1 || k == 2 || k == 4);
661         assert(dalign >= k);
662         if (k == 1)
663                 print("stb %%r%d,[%%r%d+%d]\n", tmp, reg, off);
664         else if (k == 2)
665                 print("sth %%r%d,[%%r%d+%d]\n", tmp, reg, off);
666         else
667                 print("st %%r%d,[%%r%d+%d]\n",  tmp, reg, off);
669 static void blkloop(dreg, doff, sreg, soff, size, tmps)
670 int dreg, doff, sreg, soff, size, tmps[]; {
671         if ((size&~7) < 4096) {
672                 print("add %%r%d,%d,%%r%d\n", sreg, size&~7, sreg);
673                 print("add %%r%d,%d,%%r%d\n", dreg, size&~7, tmps[2]);
674         } else {
675                 print("set %d,%%r%d\n", size&~7, tmps[2]);
676                 print("add %%r%d,%%r%d,%%r%d\n", sreg, tmps[2], sreg);
677                 print("add %%r%d,%%r%d,%%r%d\n", dreg, tmps[2], tmps[2]);
678         }
679         blkcopy(tmps[2], doff, sreg, soff, size&7, tmps);
680         print("1: dec 8,%%r%d\n", tmps[2]);
681         blkcopy(tmps[2], doff, sreg, soff - 8, 8, tmps);
682         print("cmp %%r%d,%%r%d; ", tmps[2], dreg);
683         print("bgt 1b; ");
684         print("dec 8,%%r%d\n", sreg);
686 static void defsymbol2(p) Symbol p; {
687         if (p->scope >= LOCAL && p->sclass == STATIC)
688                 p->x.name = stringf(".%d", genlabel(1));
689         else
690                 assert(p->scope != CONSTANTS || isint(p->type) || isptr(p->type)),
691                 p->x.name = p->name;
692         if (p->scope >= LABELS)
693                 p->x.name = stringf(p->generated ? ".L%s" : "%s",
694                         p->x.name);
697 static void global2(p) Symbol p; {
698         assert(p->u.seg);
699         if (p->sclass != STATIC && !p->generated)
700                 print(".type %s,#%s\n", p->x.name,
701                         isfunc(p->type) ? "function" : "object");
702         if (p->u.seg == BSS && p->sclass == STATIC)
703                 print(".local %s\n.common %s,%d,%d\n", p->x.name, p->x.name,
704                         p->type->size, p->type->align);
705         else if (p->u.seg == BSS && Aflag >= 2)
706                 print(".align %d\n%s:.skip %d\n", p->type->align, p->x.name,
707                         p->type->size);
708         else if (p->u.seg == BSS)
709                 print(".common %s,%d,%d\n", p->x.name, p->type->size, p->type->align);
710         else
711                 print(".align %d\n%s:\n", p->type->align, p->x.name);
714 static void segment2(n) int n; {
715         cseg = n;
716         switch (n) {
717         case CODE: print(".section \".text\"\n");   break;
718         case BSS:  print(".section \".bss\"\n");    break;
719         case DATA: print(".section \".data\"\n");   break;
720         case LIT:  print(".section \".rodata\"\n"); break;
721         }
723 #ifdef sparc
724 #include <stab.h>
725 static char *currentfile;       /* current file name */
726 static int ntypes;
728 static void stabblock ARGS((int, int, Symbol*));
729 static void stabfend ARGS((Symbol, int));
730 static void stabinit ARGS((char *, int, char *[]));
731 static void stabline ARGS((Coordinate *));
732 static void stabsym ARGS((Symbol));
733 static void stabtype ARGS((Symbol));
735 static void asgncode ARGS((Type, int));
736 static void dbxout ARGS((Type));
737 static int dbxtype ARGS((Type));
738 static int emittype ARGS((Type, int, int));
740 /* asgncode - assign type code to ty */
741 static void asgncode(ty, lev) Type ty; int lev; {
742         if (ty->x.marked || ty->x.typeno)
743                 return;
744         ty->x.marked = 1;
745         switch (ty->op) {
746         case VOLATILE: case CONST: case VOLATILE+CONST:
747                 asgncode(ty->type, lev);
748                 ty->x.typeno = ty->type->x.typeno;
749                 break;
750         case POINTER: case FUNCTION: case ARRAY:
751                 asgncode(ty->type, lev + 1);
752                 /* fall thru */
753         case VOID: case CHAR: case SHORT: case INT: case UNSIGNED:
754         case FLOAT: case DOUBLE:
755                 break;
756         case STRUCT: case UNION: {
757                 Field p;
758                 for (p = fieldlist(ty); p; p = p->link)
759                         asgncode(p->type, lev + 1);
760                 /* fall thru */
761         case ENUM:
762                 if (ty->x.typeno == 0)
763                         ty->x.typeno = ++ntypes;
764                 if (lev > 0 && (*ty->u.sym->name < '0' || *ty->u.sym->name > '9'))
765                         dbxout(ty);
766                 break;
767                 }
768         default:
769                 assert(0);
770         }
773 /* dbxout - output .stabs entry for type ty */
774 static void dbxout(ty) Type ty; {
775         ty = unqual(ty);
776         if (!ty->x.printed) {
777                 int col = 0;
778                 print(".stabs \""), col += 8;
779                 if (ty->u.sym && !(isfunc(ty) || isarray(ty) || isptr(ty)))
780                         print("%s", ty->u.sym->name), col += strlen(ty->u.sym->name);
781                 print(":%c", isstruct(ty) || isenum(ty) ? 'T' : 't'), col += 2;
782                 emittype(ty, 0, col);
783                 print("\",%d,0,0,0\n", N_LSYM);
784         }
787 /* dbxtype - emit a stabs entry for type ty, return type code */
788 static int dbxtype(ty) Type ty; {
789         asgncode(ty, 0);
790         dbxout(ty);
791         return ty->x.typeno;
795  * emittype - emit ty's type number, emitting its definition if necessary.
796  * Returns the output column number after emission; col is the approximate
797  * output column before emission and is used to emit continuation lines for long
798  * struct, union, and enum types. Continuations are not emitted for other types,
799  * even if the definition is long. lev is the depth of calls to emittype.
800  */
801 static int emittype(ty, lev, col) Type ty; int lev, col; {
802         int tc = ty->x.typeno;
804         if (isconst(ty) || isvolatile(ty)) {
805                 col = emittype(ty->type, lev, col);
806                 ty->x.typeno = ty->type->x.typeno;
807                 ty->x.printed = 1;
808                 return col;
809         }
810         if (tc == 0) {
811                 ty->x.typeno = tc = ++ntypes;
812 /*              fprint(2,"`%t'=%d\n", ty, tc); */
813         }
814         print("%d", tc), col += 3;
815         if (ty->x.printed)
816                 return col;
817         ty->x.printed = 1;
818         switch (ty->op) {
819         case VOID:      /* void is defined as itself */
820                 print("=%d", tc), col += 1+3;
821                 break;
822         case CHAR:      /* unsigned char is a subrange of int */
823                 if (ty == unsignedchar)
824                         print("=r1;0;255;"), col += 10;
825                 else    /* following pcc, char is a subrange of itself */
826                         print("=r%d;-128;127;", tc), col += 2+3+10;
827                 break;
828         case SHORT:     /* short is a subrange of int */
829                 if (ty == unsignedshort)
830                         print("=r1;0;65535;"), col += 12;
831                 else    /* signed */
832                         print("=r1;-32768;32767;"), col += 17;
833                 break;
834         case INT:       /* int is a subrange of itself */
835                 print("=r1;%d;%d;", INT_MIN, INT_MAX), col += 4+11+1+10+1;
836                 break;
837         case UNSIGNED:  /* unsigned is a subrange of int */
838                 print("=r1;0;-1;"), col += 9;
839                 break;
840         case FLOAT: case DOUBLE:        /* float, double get sizes instead of ranges */
841                 print("=r1;%d;0;", ty->size), col += 4+1+3;
842                 break;
843         case POINTER:
844                 print("=*"), col += 2;
845                 col = emittype(ty->type, lev + 1, col);
846                 break;
847         case FUNCTION:
848                 print("=f"), col += 2;
849                 col = emittype(ty->type, lev + 1, col);
850                 break;
851         case ARRAY:     /* array includes subscript as an int range */
852                 if (ty->size && ty->type->size)
853                         print("=ar1;0;%d;", ty->size/ty->type->size - 1), col += 7+3+1;
854                 else
855                         print("=ar1;0;-1;"), col += 10;
856                 col = emittype(ty->type, lev + 1, col);
857                 break;
858         case STRUCT: case UNION: {
859                 Field p;
860                 if (!ty->u.sym->defined) {
861                         print("=x%c%s:", ty->op == STRUCT ? 's' : 'u', ty->u.sym->name);
862                         col += 2+1+strlen(ty->u.sym->name)+1;
863                         break;
864                 }
865                 if (lev > 0 && (*ty->u.sym->name < '0' || *ty->u.sym->name > '9')) {
866                         ty->x.printed = 0;
867                         break;
868                 }
869                 print("=%c%d", ty->op == STRUCT ? 's' : 'u', ty->size), col += 1+1+3;
870                 for (p = fieldlist(ty); p; p = p->link) {
871                         if (p->name)
872                                 print("%s:", p->name), col += strlen(p->name)+1;
873                         else
874                                 print(":"), col += 1;
875                         col = emittype(p->type, lev + 1, col);
876                         if (p->lsb)
877                                 print(",%d,%d;", 8*p->offset +
878                                         (IR->little_endian ? fieldright(p) : fieldleft(p)),
879                                         fieldsize(p));
880                         else
881                                 print(",%d,%d;", 8*p->offset, 8*p->type->size);
882                         col += 1+3+1+3+1;       /* accounts for ,%d,%d; */
883                         if (col >= 80 && p->link) {
884                                 print("\\\\\",%d,0,0,0\n.stabs \"", N_LSYM);
885                                 col = 8;
886                         }
887                 }
888                 print(";"), col += 1;
889                 break;
890                 }
891         case ENUM: {
892                 Symbol *p;
893                 if (lev > 0 && (*ty->u.sym->name < '0' || *ty->u.sym->name > '9')) {
894                         ty->x.printed = 0;
895                         break;
896                 }
897                 print("=e"), col += 2;
898                 for (p = ty->u.sym->u.idlist; *p; p++) {
899                         print("%s:%d,", (*p)->name, (*p)->u.value), col += strlen((*p)->name)+3;
900                         if (col >= 80 && p[1]) {
901                                 print("\\\\\",%d,0,0,0\n.stabs \"", N_LSYM);
902                                 col = 8;
903                         }
904                 }
905                 print(";"), col += 1;
906                 break;
907                 }
908         default:
909                 assert(0);
910         }
911         return col;
914 /* stabblock - output a stab entry for '{' or '}' at level lev */
915 static void stabblock(brace, lev, p) int brace, lev; Symbol *p; {
916         if (brace == '{')
917                 while (*p)
918                         stabsym(*p++);
919         print(".stabd 0x%x,0,%d\n", brace == '{' ? N_LBRAC : N_RBRAC, lev);
922 /* stabfend - end of function p */
923 static void stabfend(p, line) Symbol p; int line; {}
925 /* stabinit - initialize stab output */
926 static void stabinit(file, argc, argv) int argc; char *file, *argv[]; {
927         typedef void (*Closure) ARGS((Symbol, void *));
929         if (file && *file) {
930                 (*IR->segment)(CODE);
931                 print("Ltext:.stabs \"%s\",0x%x,0,0,Ltext\n", file, N_SO);
932                 currentfile = file;
933         }
934         dbxtype(inttype);
935         dbxtype(chartype);
936         dbxtype(doubletype);
937         dbxtype(floattype);
938         dbxtype(longdouble);
939         dbxtype(longtype);
940         dbxtype(shorttype);
941         dbxtype(signedchar);
942         dbxtype(unsignedchar);
943         dbxtype(unsignedlong);
944         dbxtype(unsignedshort);
945         dbxtype(unsignedtype);
946         dbxtype(voidtype);
947         foreach(types, GLOBAL, (Closure)stabtype, NULL);
950 /* stabline - emit stab entry for source coordinate *cp */
951 static void stabline(cp) Coordinate *cp; {
952         if (cp->file && cp->file != currentfile) {
953                 int lab = genlabel(1);
954                 print("L%d: .stabs \"%s\",0x%x,0,0,L%d\n", lab,
955                                 cp->file, N_SOL, lab);
956                 currentfile = cp->file;
957         }
958         print(".stabd 0x%x,0,%d\n", N_SLINE, cp->y);
961 /* stabsym - output a stab entry for symbol p */
962 static void stabsym(p) Symbol p; {
963         int code, tc, sz = p->type->size;
965         if (p->generated || p->computed)
966                 return;
967         if (isfunc(p->type)) {
968                 print(".stabs \"%s:%c%d\",%d,0,0,%s\n", p->name,
969                         p->sclass == STATIC ? 'f' : 'F', dbxtype(freturn(p->type)),
970                         N_FUN, p->x.name);
971                 return;
972         }
973         if (!IR->wants_argb && p->scope == PARAM && p->structarg) {
974                 assert(isptr(p->type) && isstruct(p->type->type));
975                 tc = dbxtype(p->type->type);
976                 sz = p->type->type->size;
977         } else
978                 tc = dbxtype(p->type);
979         if (p->sclass == AUTO && p->scope == GLOBAL || p->sclass == EXTERN) {
980                 print(".stabs \"%s:G", p->name);
981                 code = N_GSYM;
982         } else if (p->sclass == STATIC) {
983                 print(".stabs \"%s:%c%d\",%d,0,0,%s\n", p->name, p->scope == GLOBAL ? 'S' : 'V',
984                         tc, p->u.seg == BSS ? N_LCSYM : N_STSYM, p->x.name);
985                 return;
986         } else if (p->sclass == REGISTER) {
987                 if (p->scope > PARAM) {
988                         int r = p->x.regnode->number;
989                         if (p->x.regnode->set == FREG)
990                                 r += 32;        /* floating point */
991                         print(".stabs \"%s:r%d\",%d,0,", p->name, tc, N_RSYM);
992                         print("%d,%d\n", sz, r);
993                 }
994                 return;
995         } else if (p->scope == PARAM) {
996                 print(".stabs \"%s:p", p->name);
997                 code = N_PSYM;
998         } else if (p->scope >= LOCAL) {
999                 print(".stabs \"%s:", p->name);
1000                 code = N_LSYM;
1001         } else
1002                 assert(0);
1003         print("%d\",%d,0,0,%s\n", tc, code,
1004                 p->scope >= PARAM && p->sclass != EXTERN ? p->x.name : "0");
1007 /* stabtype - output a stab entry for type *p */
1008 static void stabtype(p) Symbol p; {
1009         if (p->type) {
1010                 if (p->sclass == 0)
1011                         dbxtype(p->type);
1012                 else if (p->sclass == TYPEDEF)
1013                         print(".stabs \"%s:t%d\",%d,0,0,0\n", p->name, dbxtype(p->type), N_LSYM);
1014         }
1016 #else
1017 #define stabblock 0
1018 #define stabinit 0
1019 #define stabline 0
1020 #define stabsym 0
1021 #define stabtype 0
1022 #endif
1023 Interface sparcIR = {
1024         1, 1, 0,  /* char */
1025         2, 2, 0,  /* short */
1026         4, 4, 0,  /* int */
1027         4, 4, 1,  /* float */
1028         8, 8, 1,  /* double */
1029         4, 4, 0,  /* T * */
1030         0, 1, 0,  /* struct */
1031         0,  /* little_endian */
1032         1,  /* mulops_calls */
1033         1,  /* wants_callb */
1034         0,  /* wants_argb */
1035         1,  /* left_to_right */
1036         0,  /* wants_dag */
1037         address,
1038         blockbeg,
1039         blockend,
1040         defaddress,
1041         defconst,
1042         defstring,
1043         defsymbol,
1044         emit,
1045         export,
1046         function,
1047         gen,
1048         global,
1049         import,
1050         local,
1051         progbeg,
1052         progend,
1053         segment,
1054         space,
1055         stabblock, 0, 0, stabinit, stabline, stabsym, stabtype,
1056         {
1057                 1,  /* max_unaligned_load */
1058                 blkfetch, blkstore, blkloop,
1059                 _label,
1060                 _rule,
1061                 _nts,
1062                 _kids,
1063                 _opname,
1064                 _arity,
1065                 _string,
1066                 _templates,
1067                 _isinstruction,
1068                 _ntname,
1069                 emit2,
1070                 doarg,
1071                 target,
1072                 clobber,
1074         }
1077 Interface solarisIR = {
1078         1, 1, 0,  /* char */
1079         2, 2, 0,  /* short */
1080         4, 4, 0,  /* int */
1081         4, 4, 1,  /* float */
1082         8, 8, 1,  /* double */
1083         4, 4, 0,  /* T * */
1084         0, 1, 0,  /* struct */
1085         0,      /* little_endian */
1086         1,      /* mulops_calls */
1087         1,      /* wants_callb */
1088         0,      /* wants_argb */
1089         1,      /* left_to_right */
1090         0,      /* wants_dag */
1091         address,
1092         blockbeg,
1093         blockend,
1094         defaddress,
1095         defconst,
1096         defstring,
1097         defsymbol2,
1098         emit,
1099         export,
1100         function,
1101         gen,
1102         global2,
1103         import,
1104         local,
1105         progbeg,
1106         progend,
1107         segment2,
1108         space,
1109         stabblock, 0, 0, stabinit, stabline, stabsym, stabtype,
1110         {
1111                 1,      /* max_unaligned_load */
1112                 blkfetch, blkstore, blkloop,
1113                 _label,
1114                 _rule,
1115                 _nts,
1116                 _kids,
1117                 _opname,
1118                 _arity,
1119                 _string,
1120                 _templates,
1121                 _isinstruction,
1122                 _ntname,
1123                 emit2,
1124                 doarg,
1125                 target,
1126                 clobber,
1128         }