Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20080622152459

Diff

Diff from 1.98 to:

Annotations

Annotate by Age | Author | Mixed | None
/fisheye/browse/pcc/pcc/arch/pdp10/local2.c

Annotated File View

ragge
1.98
1 /*      $Id: local2.c,v 1.98 2008/06/22 15:24:59 ragge Exp $    */
ragge
1.52
2 /*
3  * Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  * 3. The name of the author may not be used to endorse or promote products
15  *    derived from this software without specific prior written permission
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28
ragge
1.1
29
30 # include "pass2.h"
31 # include <ctype.h>
32
33 # define putstr(s)      fputs((s), stdout)
34
ragge
1.83
35 void acon(FILE *, NODE *p);
ragge
1.2
36 int argsize(NODE *p);
37 void genargs(NODE *p);
ragge
1.1
38
ragge
1.44
39 static int offlab;
ragge
1.57
40 int offarg;
ragge
1.91
41 static int addto;
42 static int regoff[16];
ragge
1.21
43
ragge
1.1
44 void
ragge
1.91
45 deflab(int label)
ragge
1.46
46 {
ragge
1.91
47         printf(LABFMT ":\n"label);
ragge
1.46
48 }
49
50 void
ragge
1.91
51 prologue(struct interpass_prolog *ipp)
ragge
1.46
52 {
ragge
1.91
53         int ij;
54
55         if (ipp->ipp_vis)
56                 printf("        .globl %s\n"ipp->ipp_name);
57         printf("%s:\n"ipp->ipp_name);
58         addto = p2maxautooff;
59         if (addto >= AUTOINIT/SZCHAR)
60                 addto -= AUTOINIT/SZCHAR;
61         addto /= SZINT/SZCHAR;  /* use words here */
62         printf("        push %s,%s\n",rnames[STKREG], rnames[FPREG]);
63         printf("        move %s,%s\n"rnames[FPREG],rnames[STKREG]);
64
65         for (i = ipp->ipp_regsj = 0i ; i >>= 1j++) {
66                 if (i & 1)
67                         regoff[j] = addto++;
68         }
69         if (addto)
70                 printf("        addi %s,0%o\n"rnames[STKREG], addto);
71         for (i = ipp->ipp_regsj = 0i ; i >>= 1j++) {
72                 if (i & 1)
73                         printf("        movem %s,%d(%s)\n",
74                             rnames[j], regoff[j], rnames[STKREG]);
75         }
ragge
1.46
76 }
77
ragge
1.91
78 void
79 eoftn(struct interpass_prolog *ipp)
80 {
81         int ij;
82
83         if (ipp->ipp_ip.ip_lbl == 0)
84                 return/* no code needs to be generated */
85         for (i = ipp->ipp_regsj = 0i ; i >>= 1j++) {
86                 if (i & 1)
87                         printf("        move %s,%d(%s)\n",
88                             rnames[j], regoff[j], rnames[STKREG]);
89         }
90         printf("        move %s,%s\n"rnames[STKREG], rnames[FPREG]);
91         printf("        pop %s,%s\n"rnames[STKREG], rnames[FPREG]);
92         printf("        popj %s,\n"rnames[STKREG]);
93 }
ragge
1.48
94
ragge
1.91
95 #if 0
ragge
1.46
96 void
ragge
1.48
97 prologue(int regsint autos)
ragge
1.43
98 {
ragge
1.56
99         int iaddto;
ragge
1.48
100
ragge
1.44
101         offlab = getlab();
ragge
1.48
102         if (regs < 0 || autos < 0) {
ragge
1.43
103                 /*
104                  * non-optimized code, jump to epilogue for code generation.
105                  */
106                 ftlab1 = getlab();
107                 ftlab2 = getlab();
108                 printf("        jrst L%d\n"ftlab1);
109                 printf("L%d:\n"ftlab2);
ragge
1.48
110         } else {
111                 /*
112                  * We here know what register to save and how much to 
113                  * add to the stack.
114                  */
ragge
1.67
115                 autos = autos + (SZINT-1);
ragge
1.65
116                 addto = (autos - AUTOINIT)/SZINT + (MAXRVAR-regs);
ragge
1.63
117                 if (addto || gflag) {
ragge
1.68
118                         printf("        push %s,%s\n",rnames[017], rnames[016]);
119                         printf("        move %s,%s\n"rnames[016],rnames[017]);
ragge
1.87
120                         for (i = regsi < MAXRVARi++) {
121                                 int db = ((i+1) < MAXRVAR);
122                                 printf("        %smovem %s,0%o(%s)\n",
123                                     db ? "d" : "",
ragge
1.68
124                                     rnames[i+1], i+1-regsrnames[016]);
ragge
1.87
125                                 if (db)
126                                         i++;
127                         }
ragge
1.63
128                         if (addto)
ragge
1.68
129                                 printf("        addi %s,0%o\n"rnames[017], addto);
ragge
1.57
130                 } else
131                         offarg = 1;
ragge
1.48
132         }
ragge
1.43
133 }
134
ragge
1.1
135 /*
136  * End of block.
137  */
138 void
ragge
1.43
139 eoftn(int regsint autosint retlab)
ragge
1.1
140 {
141         register OFFSZ spoff;   /* offset from stack pointer */
ragge
1.44
142         int i;
ragge
1.1
143
ragge
1.67
144         spoff = autos + (SZINT-1);
ragge
1.1
145         if (spoff >= AUTOINIT)
146                 spoff -= AUTOINIT;
147         spoff /= SZINT;
148         /* return from function code */
ragge
1.43
149         printf("L%d:\n"retlab);
ragge
1.65
150         if (gflag || isoptim == 0 || autos != AUTOINIT || regs != MAXRVAR) {
ragge
1.87
151                 for (i = regsi < MAXRVARi++) {
152                         int db = ((i+1) < MAXRVAR);
153                         printf("        %smove %s,0%o(%s)\n"db ? "d" : "",
ragge
1.68
154                             rnames[i+1], i+1-regsrnames[016]);
ragge
1.87
155                         if (db)
156                                 i++;
157                 }
ragge
1.68
158                 printf("        move %s,%s\n"rnames[017], rnames[016]);
159                 printf("        pop %s,%s\n"rnames[017], rnames[016]);
ragge
1.56
160         }
ragge
1.68
161         printf("        popj %s,\n"rnames[017]);
ragge
1.1
162
163         /* Prolog code */
ragge
1.48
164         if (isoptim == 0) {
165                 printf("L%d:\n"ftlab1);
ragge
1.68
166                 printf("        push %s,%s\n"rnames[017], rnames[016]);
167                 printf("        move %s,%s\n"rnames[016], rnames[017]);
ragge
1.48
168                 for (i = regsi < MAXRVARi++) {
ragge
1.87
169                         int db = ((i+1) < MAXRVAR);
170                         printf("        %smovem %s,0%o(%s)\n"db ? "d" : "",
ragge
1.68
171                             rnames[i+1], i+1-regsrnames[016]);
ragge
1.48
172                         spoff++;
ragge
1.87
173                         if (db)
174                                 i++, spoff++;
ragge
1.48
175                 }
176                 if (spoff)
ragge
1.68
177                         printf("        addi %s,0%llo\n"rnames[017], spoff);
ragge
1.48
178                 printf("        jrst L%d\n"ftlab2);
ragge
1.44
179         }
180         printf("        .set " LABFMT ",0%o\n"offlabMAXRVAR-regs);
ragge
1.57
181         offarg = isoptim = 0;
ragge
1.46
182 }
ragge
1.91
183 #endif
ragge
1.1
184
ragge
1.3
185 /*
186  * add/sub/...
187  *
188  * Param given:
189  *      R - Register
190  *      M - Memory
191  *      C - Constant
192  */
ragge
1.1
193 void
194 hopcode(int fint o)
195 {
ragge
1.76
196         cerror("hopcode: f %d %d"fo);
ragge
1.1
197 }
198
199 char *
200 rnames[] = {  /* keyed to register number tokens */
ragge
1.68
201         "%0""%1""%2""%3""%4""%5""%6""%7",
202         "%10""%11""%12""%13""%14""%15""%16""%17",
ragge
1.91
203         "%0""%1""%2""%3""%4""%5""%6""%7",
204         "%10""%11""%12""%13""%14""%15",
ragge
1.1
205 };
206
207 int
208 tlen(pNODE *p;
209 {
ragge
1.41
210         switch(p->n_type) {
ragge
1.1
211                 case CHAR:
212                 case UCHAR:
213                         return(1);
214
215                 case SHORT:
216                 case USHORT:
217                         return(SZSHORT/SZCHAR);
218
219                 case DOUBLE:
220                         return(SZDOUBLE/SZCHAR);
221
222                 case INT:
223                 case UNSIGNED:
224                 case LONG:
225                 case ULONG:
226                         return(SZINT/SZCHAR);
227
228                 case LONGLONG:
229                 case ULONGLONG:
230                         return SZLONGLONG/SZCHAR;
231
232                 default:
ragge
1.41
233                         if (!ISPTR(p->n_type))
ragge
1.1
234                                 cerror("tlen type %d not pointer");
ragge
1.91
235                         return SZPOINT(0)/SZCHAR;
ragge
1.1
236                 }
237 }
ragge
1.62
238
ragge
1.8
239 static char *
ragge
1.17
240 binskip[] = {
241         "e",    /* jumpe */
242         "n",    /* jumpn */
243         "le",   /* jumple */
244         "l",    /* jumpl */
245         "ge",   /* jumpge */
246         "g",    /* jumpg */
247 };
248
249 /*
ragge
1.66
250  * Extract the higher 36 bits from a longlong.
251  */
252 static CONSZ
253 gethval(CONSZ lval)
254 {
255         CONSZ hval = (lval >> 35) & 03777777777LL;
256
257         if ((hval & 03000000000LL) == 03000000000LL) {
258                 hval |= 0777000000000LL;
259         } else if ((hval & 03000000000LL) == 02000000000LL) {
260                 hval &= 01777777777LL;
261                 hval |= 0400000000000LL;
262         }
263         return hval;
264 }
265
266 /*
ragge
1.17
267  * Do a binary comparision, and jump accordingly.
268  */
ragge
1.8
269 static void
ragge
1.17
270 twocomp(NODE *p)
ragge
1.8
271 {
ragge
1.41
272         int o = p->n_op;
ragge
1.17
273         extern int negrel[];
ragge
1.41
274         int isscon = 0iscon = p->n_right->n_op == ICON;
ragge
1.17
275
276         if (o < EQ || o > GT)
277                 cerror("bad binary conditional branch: %s"opst[o]);
ragge
1.8
278
ragge
1.41
279         if (iscon && p->n_right->n_name[0] != 0) {
ragge
1.35
280                 printf("        cam%s "binskip[negrel[o-EQ]-EQ]);
ragge
1.83
281                 adrput(stdoutgetlr(p'L'));
ragge
1.35
282                 putchar(',');
283                 printf("[ .long ");
ragge
1.83
284                 adrput(stdoutgetlr(p'R'));
ragge
1.35
285                 putchar(']');
ragge
1.41
286                 printf("\n      jrst L%d\n"p->n_label);
ragge
1.35
287                 return;
288         }
ragge
1.17
289         if (iscon)
ragge
1.41
290                 isscon = p->n_right->n_lval >= 0 &&
291                     p->n_right->n_lval < 01000000;
ragge
1.17
292
293         printf("        ca%c%s "iscon && isscon ? 'i' : 'm',
294             binskip[negrel[o-EQ]-EQ]);
ragge
1.83
295         adrput(stdoutgetlr(p'L'));
ragge
1.17
296         putchar(',');
297         if (iscon && (isscon == 0)) {
298                 printf("[ .long ");
ragge
1.83
299                 adrput(stdoutgetlr(p'R'));
ragge
1.17
300                 putchar(']');
301         } else
ragge
1.83
302                 adrput(stdoutgetlr(p'R'));
ragge
1.41
303         printf("\n      jrst L%d\n"p->n_label);
ragge
1.8
304 }
305
ragge
1.10
306 /*
ragge
1.24
307  * Compare byte/word pointers.
308  * XXX - do not work for highest bit set in address
309  */
310 static void
311 ptrcomp(NODE *p)
312 {
ragge
1.83
313         printf("        rot "); adrput(stdoutgetlr(p'L')); printf(",6\n");
314         printf("        rot "); adrput(stdoutgetlr(p'R')); printf(",6\n");
ragge
1.24
315         twocomp(p);
316 }
317
318 /*
ragge
1.18
319  * Do a binary comparision of two long long, and jump accordingly.
320  * XXX - can optimize for constants.
321  */
322 static void     
323 twollcomp(NODE *p)
324 {       
ragge
1.41
325         int o = p->n_op;
326         int iscon = p->n_right->n_op == ICON;
ragge
1.91
327         int m = 0/* XXX gcc */
ragge
1.18
328
329         if (o < EQ || o > GT)
330                 cerror("bad long long conditional branch: %s"opst[o]);
331
332         /* Special strategy for equal/not equal */
333         if (o == EQ || o == NE) {
334                 if (o == EQ)
335                         m = getlab();
336                 printf("        came ");
337                 upput(getlr(p'L'), SZLONG);
338                 putchar(',');
339                 if (iscon)
340                         printf("[ .long ");
341                 upput(getlr(p'R'), SZLONG);
342                 if (iscon)
343                         putchar(']');
ragge
1.41
344                 printf("\n      jrst L%d\n"o == EQ ? m : p->n_label);
ragge
1.18
345                 printf("        cam%c "o == EQ ? 'n' : 'e');
ragge
1.83
346                 adrput(stdoutgetlr(p'L'));
ragge
1.18
347                 putchar(',');
348                 if (iscon)
349                         printf("[ .long ");
ragge
1.83
350                 adrput(stdoutgetlr(p'R'));
ragge
1.18
351                 if (iscon)
352                         putchar(']');
ragge
1.41
353                 printf("\n      jrst L%d\n"p->n_label);
ragge
1.18
354                 if (o == EQ)
355                         printf("L%d:\n"m);
356                 return;
357         }
ragge
1.34
358         /* First test highword */
ragge
1.18
359         printf("        cam%ce "o == GT || o == GE ? 'l' : 'g');
ragge
1.83
360         adrput(stdoutgetlr(p'L'));
ragge
1.18
361         putchar(',');
362         if (iscon)
363                 printf("[ .long ");
ragge
1.83
364         adrput(stdoutgetlr(p'R'));
ragge
1.18
365         if (iscon)
366                 putchar(']');
ragge
1.41
367         printf("\n      jrst L%d\n"p->n_label);
ragge
1.18
368
369         /* Test equality */
370         printf("        came ");
ragge
1.83
371         adrput(stdoutgetlr(p'L'));
ragge
1.18
372         putchar(',');
373         if (iscon)
374                 printf("[ .long ");
ragge
1.83
375         adrput(stdoutgetlr(p'R'));
ragge
1.18
376         if (iscon)
377                 putchar(']');
378         printf("\n      jrst L%d\n"m = getlab());
379
ragge
1.34
380         /* Test lowword. Only works with pdp10 format for longlongs */
ragge
1.18
381         printf("        cam%c%c "o == GT || o == GE ? 'l' : 'g',
382             o == LT || o == GT ? 'e' : ' ');
ragge
1.34
383         upput(getlr(p'L'), SZLONG);
ragge
1.18
384         putchar(',');
385         if (iscon)  
386                 printf("[ .long ");
ragge
1.34
387         upput(getlr(p'R'), SZLONG);
ragge
1.18
388         if (iscon)
389                 putchar(']');
ragge
1.41
390         printf("\n      jrst L%d\n"p->n_label);
ragge
1.18
391         printf("L%d:\n"m);
392 }
393
394 /*
ragge
1.10
395  * Print the correct instruction for constants.
396  */
397 static void
398 constput(NODE *p)
399 {
ragge
1.41
400         CONSZ val = p->n_right->n_lval;
401         int reg = p->n_left->n_rval;
ragge
1.10
402
403         /* Only numeric constant */
ragge
1.49
404         if (p->n_right->n_name[0] == '\0') {
ragge
1.10
405                 if (val == 0) {
ragge
1.15
406                         printf("movei %s,0"rnames[reg]);
ragge
1.89
407                 } else if ((val & 0777777000000LL) == 0) {
ragge
1.12
408                         printf("movei %s,0%llo"rnames[reg], val);
ragge
1.10
409                 } else if ((val & 0777777) == 0) {
ragge
1.12
410                         printf("hrlzi %s,0%llo"rnames[reg], val >> 18);
ragge
1.10
411                 } else {
ragge
1.87
412                         printf("move %s,[ .long 0%llo]"rnames[reg],
413                             szty(p->n_right->n_type) > 1 ? val :
ragge
1.89
414                             val & 0777777777777LL);
ragge
1.10
415                 }
416                 /* Can have more tests here, hrloi etc */
417                 return;
418         } else {
ragge
1.70
419                 printf("xmovei %s,%s"rnames[reg], p->n_right->n_name);
420                 if (val)
421                         printf("+" CONFMTval);
ragge
1.10
422         }
423 }
424
ragge
1.11
425 /*
426  * Return true if the constant can be bundled in an instruction (immediate).
427  */
428 static int
429 oneinstr(NODE *p)
430 {
ragge
1.41
431         if (p->n_name[0] != '\0')
ragge
1.11
432                 return 0;
ragge
1.41
433         if ((p->n_lval & 0777777000000ULL) != 0)
ragge
1.11
434                 return 0;
435         return 1;
436 }
437
ragge
1.17
438 /*
ragge
1.71
439  * Emit a halfword or byte instruction, from OREG to REG.
ragge
1.20
440  * Sign extension must also be done here.
441  */
442 static void
443 emitshort(NODE *p)
444 {
ragge
1.41
445         CONSZ off = p->n_lval;
ragge
1.71
446         TWORD type = p->n_type;
ragge
1.41
447         int reg = p->n_rval;
ragge
1.71
448         int issigned = !ISUNSIGNED(type);
449         int ischar = type == CHAR || type == UCHAR;
450         int reg1 = getlr(p'1')->n_rval;
451
452         if (off < 0) { /* argument, use move instead */
453                 printf("        move ");
454         } else if (off == 0 && p->n_name[0] == 0) {
455                 printf("        ldb %s,%s\n"rnames[reg1], rnames[reg]);
456                 /* XXX must sign extend here even if not necessary */
457                 switch (type) {
458                 case CHAR:
459                         printf("        lsh %s,033\n"rnames[reg1]);
460                         printf("        ash %s,-033\n"rnames[reg1]);
461                         break;
462                 case SHORT:
463                         printf("        hrre %s,%s\n",
464                             rnames[reg1], rnames[reg1]);
465                         break;
466                 }
467                 return;
468         } else if (ischar) {
ragge
1.89
469                 if (off >= 0700000000000LL && p->n_name[0] != '\0') {
ragge
1.71
470                         cerror("emitsh");
471                         /* reg contains index integer */
ragge
1.91
472 //                      if (!istreg(reg))
473 //                              cerror("emitshort !istreg");
ragge
1.71
474                         printf("        adjbp %s,[ .long 0%llo+%s ]\n",
475                             rnames[reg], offp->n_name);
ragge
1.23
476                         printf("        ldb ");
ragge
1.83
477                         adrput(stdoutgetlr(p'1'));
ragge
1.71
478                         printf(",%s\n"rnames[reg]);
479                         goto signe;
ragge
1.20
480                 }
ragge
1.21
481                 printf("        ldb ");
ragge
1.83
482                 adrput(stdoutgetlr(p'1'));
ragge
1.71
483                 if (off)
484                         printf(",[ .long 0%02o11%02o%06o ]\n",
485                             (int)(27-(9*(off&3))), reg, (int)off/4);
486                 else
487                         printf(",%s\n"rnames[reg]);
488 signe:          if (issigned) {
489                         printf("        lsh ");
ragge
1.83
490                         adrput(stdoutgetlr(p'1'));
ragge
1.71
491                         printf(",033\n  ash ");
ragge
1.83
492                         adrput(stdoutgetlr(p'1'));
ragge
1.71
493                         printf(",-033\n");
ragge
1.21
494                 }
495                 return;
ragge
1.71
496         } else {
497                 printf("        h%cr%c "off & 1 ? 'r' : 'l',
498                     issigned ? 'e' : 'z');
ragge
1.21
499         }
ragge
1.71
500         p->n_lval /= (ischar ? 4 : 2);
ragge
1.83
501         adrput(stdoutgetlr(p'1'));
ragge
1.20
502         putchar(',');
ragge
1.83
503         adrput(stdoutgetlr(p'L'));
ragge
1.20
504         putchar('\n');
505 }
506
507 /*
508  * Store a short from a register. Destination is a OREG.
509  */
510 static void
511 storeshort(NODE *p)
512 {
ragge
1.41
513         NODE *l = p->n_left;
514         CONSZ off = l->n_lval;
515         int reg = l->n_rval;
516         int ischar = BTYPE(p->n_type) == CHAR || BTYPE(p->n_type) == UCHAR;
ragge
1.21
517
ragge
1.41
518         if (l->n_op == NAME) {
ragge
1.21
519                 if (ischar) {
520                         printf("        dpb ");
ragge
1.83
521                         adrput(stdoutgetlr(p'R'));
ragge
1.21
522                         printf(",[ .long 0%02o%010o+%s ]\n",
ragge
1.41
523                             070+((int)off&3), (int)(off/4), l->n_name);
ragge
1.21
524                         return;
525                 }
526                 printf("        hr%cm "off & 1 ? 'r' : 'l');
ragge
1.41
527                 l->n_lval /= 2;
ragge
1.83
528                 adrput(stdoutgetlr(p'R'));
ragge
1.21
529                 putchar(',');   
ragge
1.83
530                 adrput(stdoutgetlr(p'L'));
ragge
1.21
531                 putchar('\n');
532                 return;
533         }
ragge
1.20
534
ragge
1.40
535         if (off || reg == FPREG) { /* Can emit halfword instructions */
ragge
1.20
536                 if (off < 0) { /* argument, use move instead */
537                         printf("        movem ");
ragge
1.21
538                 } else if (ischar) {
539                         printf("        dpb ");
ragge
1.83
540                         adrput(stdoutgetlr(p'1'));
ragge
1.21
541                         printf(",[ .long 0%02o11%02o%06o ]\n",
542                             (int)(27-(9*(off&3))), reg, (int)off/4);
543                         return;
ragge
1.20
544                 } else {
545                         printf("        hr%cm "off & 1 ? 'r' : 'l');
546                 }
ragge
1.41
547                 l->n_lval /= 2;
ragge
1.83
548                 adrput(stdoutgetlr(p'R'));
ragge
1.20
549                 putchar(',');
ragge
1.83
550                 adrput(stdoutgetlr(p'L'));
ragge
1.20
551         } else {
552                 printf("        dpb ");
ragge
1.83
553                 adrput(stdoutgetlr(p'R'));
ragge
1.20
554                 putchar(',');
555                 l = getlr(p'L');
ragge
1.41
556                 l->n_op = REG;
ragge
1.83
557                 adrput(stdoutl);
ragge
1.41
558                 l->n_op = OREG;
ragge
1.20
559         }
560         putchar('\n');
561 }
562
563 /*
ragge
1.25
564  * Multiply a register with a constant.
565  */
566 static void     
567 imuli(NODE *p)
568 {
ragge
1.41
569         NODE *r = p->n_right;
ragge
1.25
570
ragge
1.41
571         if (r->n_lval >= 0 && r->n_lval <= 0777777) {
ragge
1.25
572                 printf("        imuli ");
ragge
1.83
573                 adrput(stdoutgetlr(p'L'));
ragge
1.41
574                 printf(",0%llo\n"r->n_lval);
ragge
1.25
575         } else {
576                 printf("        imul ");
ragge
1.83
577                 adrput(stdoutgetlr(p'L'));
ragge
1.89
578                 printf(",[ .long 0%llo ]\n"r->n_lval & 0777777777777LL);
ragge
1.25
579         }
580 }
581
ragge
1.26
582 /*
583  * Divide a register with a constant.
584  */
585 static void     
586 idivi(NODE *p)
587 {
ragge
1.41
588         NODE *r = p->n_right;
ragge
1.26
589
ragge
1.41
590         if (r->n_lval >= 0 && r->n_lval <= 0777777) {
ragge
1.26
591                 printf("        idivi ");
ragge
1.83
592                 adrput(stdoutgetlr(p'1'));
ragge
1.41
593                 printf(",0%llo\n"r->n_lval);
ragge
1.26
594         } else {
595                 printf("        idiv ");
ragge
1.83
596                 adrput(stdoutgetlr(p'1'));
ragge
1.89
597                 printf(",[ .long 0%llo ]\n"r->n_lval & 0777777777777LL);
ragge
1.26
598         }
599 }
600
ragge
1.27
601 /*
602  * move a constant into a register.
603  */
604 static void
605 xmovei(NODE *p)
606 {
607         /*
608          * Trick: If this is an unnamed constant, just move it directly,
609          * otherwise use xmovei to get section number.
610          */
ragge
1.41
611         if (p->n_name[0] == '\0' || p->n_lval > 0777777) {
ragge
1.27
612                 printf("        ");
613                 zzzcode(p'D');
614                 putchar(' ');
ragge
1.83
615                 adrput(stdoutgetlr(p'1'));
ragge
1.27
616                 putchar(',');
617                 zzzcode(p'E');
618         } else {
619                 printf("        xmovei ");
ragge
1.83
620                 adrput(stdoutgetlr(p'1'));
ragge
1.41
621                 printf(",%s"p->n_name);
622                 if (p->n_lval != 0)
623                         printf("+0%llo"p->n_lval);
ragge
1.27
624         }
625         putchar('\n');
626 }
627
ragge
1.39
628 static void
629 printcon(NODE *p
630 {
631         CONSZ cz;
632
ragge
1.41
633         p = p->n_left;
ragge
1.89
634         if (p->n_lval >= 0700000000000LL) {
ragge
1.39
635                 /* converted to pointer in clocal() */
ragge
1.91
636                 conput(0p);
ragge
1.39
637                 return;
638         }
ragge
1.41
639         if (p->n_lval == 0 && p->n_name[0] == '\0') {
ragge
1.39
640                 putchar('0');
641                 return;
642         }
ragge
1.41
643         if (BTYPE(p->n_type) == CHAR || BTYPE(p->n_type) == UCHAR)
644                 cz = (p->n_lval/4) | ((p->n_lval & 3) << 30);
ragge
1.39
645         else
ragge
1.41
646                 cz = (p->n_lval/2) | (((p->n_lval & 1) + 5) << 30);
ragge
1.89
647         cz |= 0700000000000LL;
ragge
1.39
648         printf("0%llo"cz);
ragge
1.41
649         if (p->n_name[0] != '\0')
650                 printf("+%s"p->n_name);
ragge
1.39
651 }
652
ragge
1.54
653 static void
654 putcond(NODE *p)
655 {               
ragge
1.91
656         char *c = 0/* XXX gcc */
ragge
1.54
657
658         switch (p->n_op) {
659         case EQc = "e"break;
660         case NEc = "n"break;
661         case LEc = "le"break;
662         case LTc = "l"break;
663         case GTc = "g"break;
664         case GEc = "ge"break;
665         default:
666                 cerror("putcond");
667         }
668         printf("%s"c);
669 }
670
ragge
1.1
671 void
672 zzzcode(NODE *pint c)
673 {
ragge
1.72
674         NODE *l;
ragge
1.66
675         CONSZ hval;
ragge
1.3
676
677         switch (c) {
ragge
1.77
678         case 'A'/* ildb right arg */
ragge
1.83
679                 adrput(stdoutp->n_left->n_left);
ragge
1.77
680                 break;
681
ragge
1.84
682         case 'B'/* remove from stack after subroutine call */
ragge
1.96
683                 if (p->n_qual)
ragge
1.92
684                         printf("        subi %%17,0%o\n"p->n_qual);
ragge
1.84
685                 break;
686
ragge
1.10
687         case 'C':
688                 constput(p);
689                 break;
690
691         case 'D'/* Find out which type of const load insn to use */
ragge
1.41
692                 if (p->n_op != ICON)
ragge
1.10
693                         cerror("zzzcode not ICON");
ragge
1.41
694                 if (p->n_name[0] == '\0') {
695                         if ((p->n_lval <= 0777777) && (p->n_lval > 0))
ragge
1.10
696                                 printf("movei");
ragge
1.41
697                         else if ((p->n_lval & 0777777) == 0)
ragge
1.10
698                                 printf("hrlzi");
699                         else
700                                 printf("move");
701                 } else
702                         printf("move");
703                 break;
704
705         case 'E'/* Print correct constant expression */
ragge
1.41
706                 if (p->n_name[0] == '\0') {
707                         if ((p->n_lval <= 0777777) && (p->n_lval > 0)){
708                                 printf("0%llo"p->n_lval);
709                         } else if ((p->n_lval & 0777777) == 0) {
710                                 printf("0%llo"p->n_lval >> 18);
ragge
1.35
711                         } else {
ragge
1.41
712                                 if (p->n_lval < 0)
713                                         printf("[ .long -0%llo]", -p->n_lval);
ragge
1.35
714                                 else
ragge
1.41
715                                         printf("[ .long 0%llo]"p->n_lval);
ragge
1.35
716                         }
ragge
1.10
717                 } else {
ragge
1.41
718                         if (p->n_lval == 0)
719                                 printf("[ .long %s]"p->n_name);
ragge
1.10
720                         else
ragge
1.12
721                                 printf("[ .long %s+0%llo]",
ragge
1.41
722                                     p->n_namep->n_lval);
ragge
1.10
723                 }
ragge
1.11
724                 break;
725
ragge
1.92
726         case 'G'/* structure argument */
727                 printf("        addl %%17,0%o\n"p->n_stsize/(SZINT/SZCHAR));
728                 printf("        foo...\n");
729                 break;
730
ragge
1.74
731         case 'P':
732                 p = getlr(p'R');
733                 /* FALLTHROUGH */
ragge
1.66
734         case 'O':
735                 /*
736                  * Print long long expression.
737                  */
738                 hval = gethval(p->n_lval);
739                 printf("[ .long 0%llo,0%llo"hval,
740                     (p->n_lval & 0377777777777LL) | (hval & 0400000000000LL));
ragge
1.59
741                 if (p->n_name[0] != '\0')
742                         printf("+%s"p->n_name);
743                 printf(" ]");
ragge
1.17
744                 break;
745
ragge
1.11
746         case 'F'/* Print an "opsimp" instruction based on its const type */
ragge
1.41
747                 hopcode(oneinstr(p->n_right) ? 'C' : 'R'p->n_op);
ragge
1.11
748                 break;
749
ragge
1.17
750         case 'H'/* Print a small constant */
ragge
1.41
751                 p = p->n_right;
752                 printf("0%llo"p->n_lval & 0777777);
ragge
1.17
753                 break;
754
ragge
1.18
755         case 'Q'/* two-param long long comparisions */
756                 twollcomp(p);
757                 break;
758
ragge
1.17
759         case 'R'/* two-param conditionals */
760                 twocomp(p);
761                 break;
762
ragge
1.20
763         case 'U':
764                 emitshort(p);
765                 break;
766                 
767         case 'V':
768                 storeshort(p);
769                 break;
770
ragge
1.24
771         case 'Z':
772                 ptrcomp(p);
ragge
1.25
773                 break;
774
775         case 'a':
776                 imuli(p);
ragge
1.24
777                 break;
778
ragge
1.26
779         case 'b':
780                 idivi(p);
781                 break;
782
ragge
1.27
783         case 'c':
784                 xmovei(p);
ragge
1.39
785                 break;
786
787         case 'd':
788                 printcon(p);
ragge
1.54
789                 break;
790
791         case 'e':
792                 putcond(p);
ragge
1.27
793                 break;
794
ragge
1.69
795         case 'g':
796                 if (p->n_right->n_op != OREG || p->n_right->n_lval != 0)
ragge
1.87
797                         comperr("bad Zg oreg");
ragge
1.69
798                 printf("%s"rnames[p->n_right->n_rval]);
ragge
1.71
799                 break;
800
ragge
1.75
801 #if 0
ragge
1.58
802         case '1'/* double upput */
803                 p = getlr(p'1');
804                 p->n_rval += 2;
ragge
1.83
805                 adrput(stdoutp);
ragge
1.58
806                 p->n_rval -= 2;
ragge
1.72
807                 break;
ragge
1.75
808 #endif
ragge
1.72
809
810         case 'i'/* Write instruction for short load from name */
811                 l = getlr(p'L');
812                 printf("        h%cr%c %s,%s+" CONFMT "\n",
813                     l->n_lval & 1 ? 'r' : 'l',
814                     ISUNSIGNED(p->n_type) ? 'z' : 'e',
815                     rnames[getlr(p'1')->n_rval],
816                     l->n_namel->n_lval >> 1);
ragge
1.58
817                 break;
818
ragge
1.3
819         default:
820                 cerror("zzzcode %c"c);
821         }
ragge
1.1
822 }
823
824 /* set up temporary registers */
825 void
826 setregs()
827 {
828         fregs = 7;      /* 7 free regs on PDP10 (1-7) */
829 }
830
831 /*ARGSUSED*/
832 int
833 rewfld(NODE *p)
834 {
835         return(1);
836 }
837
838 int
stefan
1.95
839 fldexpand(NODE *pint cookiechar **cp)
840 {
841         return 0;
842 }
843
844 int
ragge
1.1
845 flshape(NODE *p)
846 {
ragge
1.41
847         register int o = p->n_op;
ragge
1.1
848
849         return (o == REG || o == NAME || o == ICON ||
ragge
1.41
850                 (o == OREG && (!R2TEST(p->n_rval) || tlen(p) == 1)));
ragge
1.1
851 }
852
853 /* INTEMP shapes must not contain any temporary registers */
854 int
855 shtemp(NODE *p)
856 {
ragge
1.91
857         return(0);
ragge
1.1
858 }
859
860 int
861 shumul(NODE *p)
862 {
863         register int o;
864
ragge
1.9
865         if (x2debug) {
ragge
1.1
866                 int val;
ragge
1.9
867                 printf("shumul(%p)\n"p);
ragge
1.1
868                 eprint(p0, &val, &val);
869         }
870
ragge
1.41
871         o = p->n_op;
ragge
1.9
872 #if 0
ragge
1.41
873         if (o == NAME || (o == OREG && !R2TEST(p->n_rval)) || o == ICON)
ragge
1.1
874                 return(STARNM);
ragge
1.9
875 #endif
ragge
1.1
876
ragge
1.91
877 #if 0
ragge
1.76
878         if ((o == INCR) &&
ragge
1.41
879             (p->n_left->n_op == REG && p->n_right->n_op == ICON) &&
880             p->n_right->n_name[0] == '\0') {
881                 switch (p->n_type) {
ragge
1.1
882                         case CHAR|PTR:
883                         case UCHAR|PTR:
884                                 o = 1;
885                                 break;
886
887                         case SHORT|PTR:
888                         case USHORT|PTR:
889                                 o = 2;
890                                 break;
891
892                         case INT|PTR:
893                         case UNSIGNED|PTR:
894                         case LONG|PTR:
895                         case ULONG|PTR:
896                         case FLOAT|PTR:
897                                 o = 4;
898                                 break;
899
900                         case DOUBLE|PTR:
901                         case LONGLONG|PTR:
902                         case ULONGLONG|PTR:
903                                 o = 8;
904                                 break;
905
906                         default:
ragge
1.41
907                                 if (ISPTR(p->n_type) &&
908                                      ISPTR(DECREF(p->n_type))) {
ragge
1.1
909                                         o = 4;
910                                         break;
911                                 } else
912                                         return(0);
913                 }
ragge
1.69
914                 return0);
ragge
1.1
915         }
ragge
1.91
916 #endif
ragge
1.1
917         return0 );
918 }