Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:plunky:20120422210740

Diff

Diff from 1.103 to:

Annotations

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

Annotated File View

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