OSDN Git Service

(add_1_to_mem): Corrected.
[pf3gnuchains/gcc-fork.git] / gcc / config / 1750a / 1750a.c
1 /* Subroutines for insn-output.c for MIL-STD-1750.
2    Copyright (C) 1994, 1995, 1996 Free Software Foundation, Inc.
3    Contributed by O.M.Kellogg, DASA (kellogg@space.otn.dasa.de)
4
5 This file is part of GNU CC.
6
7 GNU CC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 1, or (at your option)
10 any later version.
11
12 GNU CC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GNU CC; see the file COPYING.  If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA.  */
21
22 #ifndef FILE
23 #include <stdio.h>
24 #endif
25 #include <string.h>
26
27 #define __datalbl
28 #include "config.h"
29 #include "rtl.h"
30 #include "tree.h"
31 #include "expr.h"
32 #define HAVE_cc0
33 #include "conditions.h"
34 #include "real.h"
35
36 struct datalabel_array datalbl[DATALBL_ARRSIZ];
37 int datalbl_ndx = -1;
38 struct jumplabel_array jmplbl[JMPLBL_ARRSIZ];
39 int jmplbl_ndx = -1;
40 int label_pending = 0, program_counter = 0;
41 enum section current_section = Normal;
42 char *sectname[4] =
43 {"Init", "Normal", "Konst", "Static"};
44
45 int
46 notice_update_cc (exp)
47      rtx exp;
48 {
49   if (GET_CODE (exp) == SET)
50     {
51       enum rtx_code src_code = GET_CODE (SET_SRC (exp));
52       /* Jumps do not alter the cc's.  */
53       if (SET_DEST (exp) == pc_rtx)
54         return;
55       /* Moving a register or constant into memory doesn't alter the cc's. */
56       if (GET_CODE (SET_DEST (exp)) == MEM
57           && (src_code == REG || src_code == CONST_INT))
58         return;
59       /* Function calls clobber the cc's.  */
60       if (src_code == CALL)
61         {
62           CC_STATUS_INIT;
63           return;
64         }
65       /* Emulated longword bit-ops leave cc's incorrect */
66       if (GET_MODE (SET_DEST (exp)) == HImode ?
67                src_code == AND || src_code == IOR ||
68                src_code == XOR || src_code == NOT : 0)
69         {
70           CC_STATUS_INIT;
71           return;
72         }
73       /* Tests and compares set the cc's in predictable ways.  */
74       if (SET_DEST (exp) == cc0_rtx)
75         {
76           CC_STATUS_INIT;
77           cc_status.value1 = SET_SRC (exp);
78           return;
79         }
80       /* Anything else will set cc_status. */
81       cc_status.flags = CC_NO_OVERFLOW;
82       cc_status.value1 = SET_SRC (exp);
83       cc_status.value2 = SET_DEST (exp);
84       return;
85     }
86   else if (GET_CODE (exp) == PARALLEL
87            && GET_CODE (XVECEXP (exp, 0, 0)) == SET)
88     {
89       if (SET_DEST (XVECEXP (exp, 0, 0)) == pc_rtx)
90         return;
91       if (SET_DEST (XVECEXP (exp, 0, 0)) == cc0_rtx)
92         {
93           CC_STATUS_INIT;
94           cc_status.value1 = SET_SRC (XVECEXP (exp, 0, 0));
95           return;
96         }
97       CC_STATUS_INIT;
98     }
99   else
100     {
101       CC_STATUS_INIT;
102     }
103 }
104
105
106 rtx
107 function_arg (cum, mode, type, named)
108      int cum;
109      enum machine_mode mode;
110      tree type;
111      int named;
112 {
113   int size;
114
115   if (MUST_PASS_IN_STACK (mode, type))
116     return (rtx) 0;
117   if (mode == BLKmode)
118     size = int_size_in_bytes (type);
119   else
120     size = GET_MODE_SIZE (mode);
121   if (cum + size < 12)
122     return gen_rtx (REG, mode, cum);
123   else
124     return (rtx) 0;
125 }
126
127
128 #ifndef STRDUP
129 char *
130 strdup (str)
131      char *str;
132 {
133   char *p;
134   if (str == NULL)
135     return NULL;
136   if ((p = (char *) malloc (strlen (str) + 1)) == NULL)
137     {
138       fprintf (stderr, "dynamic memory exhausted");
139       abort ();
140     }
141   return strcpy (p, str);
142 }
143
144 #endif
145
146
147 double
148 get_double (x)
149      rtx x;
150 {
151   union
152     {
153       double d;
154       long i[2];
155     }
156   du;
157
158   du.i[0] = CONST_DOUBLE_LOW (x);
159   du.i[1] = CONST_DOUBLE_HIGH (x);
160   return du.d;
161 }
162
163 char *
164 float_label (code, value)
165      char code;
166      double value;
167 {
168   int i = 1;
169   static char label[32];
170   char *p;
171
172   label[0] = code;
173   p = label + 1;
174   sprintf (p, "%lf", value);
175   while (*p)
176     {
177       *p = (*p == '+') ? 'p' :
178         (*p == '-') ? 'm' : *p;
179       p++;
180     }
181   return strdup (label);
182 }
183
184
185 char *
186 movcnt_regno_adjust (op)
187      rtx *op;
188 {
189   static char outstr[80];
190   int op0r = REGNO (op[0]), op1r = REGNO (op[1]), op2r = REGNO (op[2]);
191 #define dstreg op0r
192 #define srcreg op1r
193 #define cntreg op2r
194 #define cntreg_1750 (op0r + 1)
195
196   if (cntreg == cntreg_1750)
197     sprintf (outstr, "mov r%d,r%d", op0r, op1r);
198   else if (dstreg + 1 == srcreg && cntreg > srcreg)
199     sprintf (outstr, "xwr r%d,r%d\n\tmov r%d,r%d", op2r, op1r, op0r, op2r);
200   else if (dstreg == cntreg + 1)
201     sprintf (outstr, "xwr r%d,r%d\n\tmov r%d,r%d", op0r, op2r, op2r, op1r);
202   else if (dstreg == srcreg + 1)
203     sprintf (outstr, "xwr r%d,r%d\n\txwr r%d,r%d\n\tmov r%d,r%d",
204              op0r, op1r, op0r, op2r, op1r, op2r);
205   else if (cntreg + 1 == srcreg)
206     sprintf (outstr, "xwr r%d,r%d\n\txwr r%d,r%d\n\tmov r%d,r%d",
207              op2r, op1r, op0r, op2r, op2r, op0r);
208   else if (cntreg == srcreg + 1)
209     sprintf (outstr, "xwr r%d,r%d\n\tmov r%d,r%d", op0r, op1r, op1r, op0r);
210   else
211     sprintf (outstr, "xwr r%d,r%d\n\tmov r%d,%d\n\txwr r%d,r%d",
212              op2r, cntreg_1750, op0r, op1r, op2r, cntreg_1750);
213   return outstr;
214 }
215
216 char *
217 mod_regno_adjust (instr, op)
218      char *instr;
219      rtx *op;
220 {
221   static char outstr[40];
222   char *r = (!strncmp (instr, "dvr", 3) ? "r" : "");
223   int modregno_gcc = REGNO (op[3]), modregno_1750 = REGNO (op[0]) + 1;
224
225   if (modregno_gcc == modregno_1750)
226     sprintf (outstr, "%s r%%0,%s%%2", instr, r);
227   else
228     sprintf (outstr, "lr r%d,r%d\n\t%s r%%0,%s%%2\n\txwr r%d,r%d",
229         modregno_gcc, modregno_1750, instr, r, modregno_1750, modregno_gcc);
230   return outstr;
231 }
232
233
234 /* Auxiliary to `nonindirect_operand':
235    Check if op is a valid memory operand for 1750A arith./logic (non-move)
236    instructions. */
237 int
238 memop_valid (op)
239      rtx op;
240 {
241   if (GET_MODE (op) != Pmode && GET_MODE (op) != VOIDmode)
242     return 0;
243   switch (GET_CODE (op))
244     {
245     case MEM:
246     case MINUS:
247     case MULT:
248     case DIV:
249       return 0;
250     case PLUS:
251       if (!memop_valid (XEXP (op, 0)))
252         return 0;
253       return memop_valid (XEXP (op, 1));
254     case REG:
255       if (REGNO (op) > 0)
256         return 1;
257       return 0;
258     case CONST:
259     case CONST_INT:
260     case SYMBOL_REF:
261     case SUBREG:
262       return 1;
263     default:
264       printf ("memop_valid: code=%d\n", (int) GET_CODE (op));
265       return 1;
266     }
267 }
268
269 /* extra predicate for recog: */
270 int
271 nonindirect_operand (op, mode)
272      rtx op;
273      enum machine_mode mode;
274 {
275   int retval;
276
277   switch (GET_CODE (op))
278     {
279     case MEM:
280       retval = memop_valid (XEXP (op, 0));
281       return retval;
282     case REG:
283       return 1;
284     default:
285       if (!CONSTANT_P (op))
286         return 0;
287     }
288   return 1;
289 }
290
291 /* predicate for the MOV instruction: */
292 int
293 mov_memory_operand (op, mode)
294      rtx op;
295      enum machine_mode mode;
296 {
297   return (GET_CODE (op) == MEM && GET_CODE (XEXP (op, 0)) == REG);
298 }
299
300 /* predicate for the STC instruction: */
301 int
302 small_nonneg_const (op, mode)
303      rtx op;
304      enum machine_mode mode;
305 {
306   if (GET_CODE (op) == CONST_INT && INTVAL (op) >= 0 && INTVAL (op) <= 15)
307     return 1;
308   return 0;
309 }
310
311 /* predicate for constant zero: */
312 int
313 zero_operand (op, mode)
314      rtx op;
315      enum machine_mode mode;
316 {
317   return op == CONST0_RTX (mode);
318 }
319
320
321 /* predicate for 1750 `B' addressing mode (Base Register with Offset)
322    memory operand */
323 int
324 b_mode_operand (op)
325      rtx op;
326 {
327   if (GET_CODE (op) == MEM)
328     {
329       rtx inner = XEXP (op, 0);
330       if (GET_CODE (inner) == REG && REG_OK_FOR_INDEX_P (inner))
331         return 1;
332       if (GET_CODE (inner) == PLUS)
333         {
334           rtx plus_op0 = XEXP (inner, 0);
335           if (GET_CODE (plus_op0) == REG && REG_OK_FOR_INDEX_P (plus_op0))
336             {
337               rtx plus_op1 = XEXP (inner, 1);
338               if (GET_CODE (plus_op1) == CONST_INT
339                   && INTVAL (plus_op1) >= 0
340                   && INTVAL (plus_op1) <= 255)
341                 return 1;
342             }
343         }
344     }
345   return 0;
346 }
347
348 /* predicate needed for adding 1 to mem (short before output) */
349 int
350 simple_memory_operand (op, mode)
351      rtx op;
352      enum machine_mode mode;
353 {
354   rtx inner;
355   if (GET_CODE (op) != MEM)
356     return 0;
357   inner = XEXP (op, 0);
358   switch (GET_CODE (inner))
359     {
360     case REG:
361     case SYMBOL_REF:
362     case LABEL_REF:
363       return 1;
364     case PLUS:
365       if (GET_CODE (XEXP (inner, 1)) != CONST_INT)
366         return 0;
367       inner = (XEXP (inner, 0));
368       switch (GET_CODE (inner))
369         {
370         case REG:
371         case SYMBOL_REF:
372         case LABEL_REF:
373           return 1;
374         case PLUS:
375           if (GET_CODE (XEXP (inner, 1)) != CONST_INT)
376             return 0;
377           switch (GET_CODE (XEXP (inner, 0)))
378             {
379             case SYMBOL_REF:
380             case LABEL_REF:
381               return 1;
382             }
383         }
384     }
385   return 0;
386 }
387
388
389 /* destructively add one to memory address */
390 add_1_to_mem (opnd)     /* returns 0 for success, -1 for failure */
391      rtx opnd;          /* OPND must be a MEM rtx */
392 {
393   rtx inner = XEXP (opnd, 0);
394
395   if (GET_CODE (opnd) != MEM)
396     {
397       fprintf (stderr, "add_1_to_mem: input is not MEM\n");
398       return -1;  /* failure */
399     }
400   switch (GET_CODE (inner))
401     {
402     case CONST:
403       inner = XEXP (inner, 0);
404       if (GET_CODE (inner) != PLUS
405        || GET_CODE (XEXP (inner, 1)) != CONST_INT)
406         {
407           fprintf (stderr, "add_1_to_mem: CONST failure\n");
408           return -1;
409         }
410       INTVAL (XEXP (XEXP (XEXP (opnd, 0), 0), 1)) += 1;
411       break;
412     case REG:
413       XEXP (opnd, 0) = gen_rtx (PLUS, Pmode, inner, const1_rtx);
414       break;
415     case SYMBOL_REF:
416     case LABEL_REF:
417       XEXP (opnd, 0) = gen_rtx (CONST, VOIDmode,
418                          gen_rtx (PLUS, Pmode, inner, const1_rtx));
419       break;
420     case PLUS:
421       inner = XEXP (inner, 1);
422       switch (GET_CODE (inner))
423         {
424         case CONST:
425           inner = XEXP (inner, 0);
426           if (GET_CODE (inner) != PLUS
427            || GET_CODE (XEXP (inner, 1)) != CONST_INT)
428             {
429               fprintf (stderr, "add_1_to_mem: PLUS CONST failure\n");
430               return -1;
431             }
432           INTVAL (XEXP (XEXP (XEXP (XEXP (opnd, 0), 1), 0), 1)) += 1;
433           break;
434         case CONST_INT:
435           INTVAL (XEXP (XEXP (opnd, 0), 1)) += 1;
436           break;
437         case SYMBOL_REF:
438         case LABEL_REF:
439           XEXP (XEXP (opnd, 0), 1) = gen_rtx (CONST, VOIDmode,
440                                      gen_rtx (PLUS, Pmode, inner, const1_rtx));
441           break;
442         default:
443           fprintf (stderr, "add_1_to_mem: PLUS failure\n");
444           return -1;
445         }
446     }
447   return 0;
448 }
449
450
451 /* Decide whether to output a conditional jump as a "Jump Conditional"
452    or as a "Branch Conditional": */
453
454 int
455 find_jmplbl (labelnum)
456      int labelnum;
457 {
458   int i, found = 0;
459
460   for (i = 0; i <= jmplbl_ndx; i++)
461     if (labelnum == jmplbl[i].num)
462       {
463         found = 1;
464         break;
465       }
466   if (found)
467     return i;
468   return -1;
469 }
470
471 char *
472 branch_or_jump (condition, targetlabel_number)
473      char *condition;
474      int targetlabel_number;
475 {
476   static char buf[30];
477   int index;
478
479   if ((index = find_jmplbl (targetlabel_number)) >= 0)
480     if (program_counter - jmplbl[index].pc < 128)
481       {
482         sprintf (buf, "b%s %%l0", condition);
483         return buf;
484       }
485   sprintf (buf, "jc %s,%%l0", condition);
486   return buf;
487 }
488
489
490 int
491 unsigned_comparison_operator (insn)
492      rtx insn;
493 {
494   switch (GET_CODE (insn))
495     {
496     case GEU:
497     case GTU:
498     case LEU:
499     case LTU:
500       return 1;
501     default:
502       return 0;
503     }
504 }
505
506 int
507 next_cc_user_is_unsigned (insn)
508      rtx insn;
509 {
510   if ( !(insn = next_cc0_user (insn)))
511     abort ();
512   else if (GET_CODE (insn) == JUMP_INSN
513            && GET_CODE (PATTERN (insn)) == SET
514            && GET_CODE (SET_SRC (PATTERN (insn))) == IF_THEN_ELSE)
515     return unsigned_comparison_operator (XEXP (SET_SRC (PATTERN (insn)), 0));
516   else if (GET_CODE (insn) == INSN
517            && GET_CODE (PATTERN (insn)) == SET)
518     return unsigned_comparison_operator (SET_SRC (PATTERN (insn)));
519   else
520     abort ();
521 }
522
523
524
525 /* The PRINT_OPERAND and PRINT_OPERAND_ADDRESS macros have been
526    made functions: */
527
528 print_operand (file, x, kode)
529      FILE *file;
530      rtx x;
531      enum rtx_code kode;
532 {
533   switch (GET_CODE (x))
534     {
535     case REG:
536       fprintf (file, "%d", REGNO (x));
537       break;
538     case SYMBOL_REF:
539       fprintf (file, "%s", XSTR (x, 0));
540       break;
541     case LABEL_REF:
542     case CONST:
543     case MEM:
544       if (kode == 'Q')
545         {
546           rtx inner = XEXP (x, 0);
547           switch (GET_CODE (inner))
548             {
549             case REG:
550               fprintf (file, "r%d,0", REGNO (inner));
551               break;
552             case PLUS:
553               fprintf (file, "r%d,%d", REGNO (XEXP (inner, 0)),
554                        INTVAL (XEXP (inner, 1)));
555               break;
556             default:
557               fprintf (file, "[ill Q code=%d]", GET_CODE (inner));
558             }
559         }
560       else
561         output_address (XEXP (x, 0));
562       break;
563     case CONST_DOUBLE:
564 /*    {
565         double value = get_double (x);
566         char fltstr[32];
567         sprintf (fltstr, "%lf", value);
568
569         if (kode == 'D' || kode == 'E')
570           {
571             int i, found = 0;
572             for (i = 0; i <= datalbl_ndx; i++)
573               if (strcmp (fltstr, datalbl[i].value) == 0)
574                 {
575                   found = 1;
576                   break;
577                 }
578             if (!found)
579               {
580                 strcpy (datalbl[i = ++datalbl_ndx].value, fltstr);
581                 datalbl[i].name = float_label (kode, value);
582                 datalbl[i].size = (kode == 'E') ? 3 : 2;
583                 check_section (Konst);
584                 fprintf (file, "K%s \tdata%s %s ;p_o\n", datalbl[i].name,
585                         (kode == 'E' ? "ef" : "f"), fltstr);
586                 check_section (Normal);
587               }
588           }
589         else if (kode == 'F' || kode == 'G')
590           {
591             int i, found = 0;
592             for (i = 0; i <= datalbl_ndx; i++)
593               if (strcmp (fltstr, datalbl[i].value) == 0)
594                 {
595                   found = 1;
596                   break;
597                 }
598             if (!found)
599               {
600                 fprintf (stderr,
601                    "float value %lfnot found upon label reference\n", value);
602                 strcpy (datalbl[i = ++datalbl_ndx].value, fltstr);
603                 datalbl[i].name = float_label (kode, value);
604                 datalbl[i].size = (kode == 'G') ? 3 : 2;
605                 check_section (Konst);
606                 fprintf (file, "K%s \tdata%s %s ;p_o\n", datalbl[i].name,
607                         (kode == 'G' ? "ef" : "f"), fltstr);
608                 check_section (Normal);
609               }
610             fprintf (file, "%s ;P_O 'F'", datalbl[i].name);
611           }
612         else
613           fprintf (file, " %s  ;P_O cst_dbl ", fltstr);
614       }
615  */
616       fprintf (file, "%lf", get_double (x));
617       break;
618     case CONST_INT:
619       if (kode == 'J')
620         fprintf (file, "%d", -INTVAL (x));
621       else if (INTVAL (x) > 0x7FFF)
622         fprintf (file, "%d  ; range correction (val>0x7FFF) applied",
623                  INTVAL (x) - 0x10000);
624       else
625         fprintf (file, "%d", INTVAL (x));
626       break;
627     case CODE_LABEL:
628       fprintf (file, "L%d", XINT (x, 3));
629       break;
630     case CALL:
631       fprintf (file, "CALL nargs=%d, func is either '%s' or '%s'",
632        XEXP (x, 1), XSTR (XEXP (XEXP (x, 0), 1), 0), XSTR (XEXP (x, 0), 1));
633       break;
634     case PLUS:
635       {
636         rtx op0 = XEXP (x, 0), op1 = XEXP (x, 1);
637         int op0code = GET_CODE (op0), op1code = GET_CODE (op1);
638         if (op1code == CONST_INT)
639           switch (op0code)
640             {
641             case REG:
642               fprintf (file, "%d,r%d  ; p_o_PLUS for REG and CONST_INT",
643                        INTVAL (op1), REGNO (op0));
644               break;
645             case SYMBOL_REF:
646               fprintf (file, "%d+%s", INTVAL (op1), XSTR (op0, 0));
647               break;
648             case MEM:
649               fprintf (file, "%d,[mem:", INTVAL (op1));
650               output_address (XEXP (op0, 0));
651               fprintf (file, "] ;P_O plus");
652               break;
653             default:
654               fprintf (file, "p_o_PLUS UFO, code=%d, with CONST=%d",
655                        (int) op0code, INTVAL (op1));
656             }
657         else if (op1code == SYMBOL_REF && op0code == REG)
658           fprintf (file, "%s,r%d  ; P_O: (plus reg sym)",
659                    XSTR (op1, 0), REGNO (op0));
660         else
661           fprintf (file, "p_o_+: op0code=%d, op1code=%d", op0code, op1code);
662       }
663       break;
664     default:
665       fprintf (file, "p_o_UFO code=%d", GET_CODE (x));
666     }
667 }
668
669 print_operand_address (file, addr)
670      FILE *file;
671      rtx addr;
672 {
673   switch (GET_CODE (addr))
674     {
675     case REG:
676       fprintf (file, "0,r%d ; P_O_A", REGNO (addr));
677       break;
678     case PLUS:
679       {
680         register rtx x = XEXP (addr, 0), y = XEXP (addr, 1);
681         switch (GET_CODE (x))
682           {
683           case REG:
684             switch (GET_CODE (y))
685               {
686               case CONST:
687                 output_address (XEXP (y, 0));
688                 fprintf (file, ",r%d ;P_O_A reg + const expr", REGNO (x));
689                 break;
690               case CONST_INT:
691                 fprintf (file, "%d,r%d", INTVAL (y), REGNO (x));
692                 break;
693               case SYMBOL_REF:
694                 fprintf (file, "%s,r%d  ; P_O_A reg + sym",
695                          XSTR (y, 0), REGNO (x));
696                 break;
697               case LABEL_REF:
698                 output_address (XEXP (y, 0));
699                 fprintf (file, ",r%d  ; P_O_A reg + label", REGNO (x));
700                 break;
701               default:
702                 fprintf (file, "[P_O_A reg%d+UFO code=%d]",
703                          REGNO (x), GET_CODE (y));
704               }
705             break;
706           case LABEL_REF:
707             output_address (XEXP (x, 0));
708             break;
709           case SYMBOL_REF:
710             switch (GET_CODE (y))
711               {
712               case CONST_INT:
713                 fprintf (file, "%d+%s", INTVAL (y), XSTR (x, 0));
714                 break;
715               case REG:
716                 fprintf (file, "%s,r%d ;P_O_A sym + reg",
717                          XSTR (x, 0), REGNO (y));
718                 break;
719               default:
720                 fprintf (file, "P_O_A sym/lab+UFO[sym=%s,code(y)=%d]",
721                          XSTR (x, 0), GET_CODE (y));
722               }
723             break;
724           case CONST:
725             output_address (XEXP (x, 0));
726             if (GET_CODE (y) == REG)
727               fprintf (file, ",r%d ;P_O_A const + reg", REGNO (x));
728             else
729               fprintf (file, "P_O_A const+UFO code(y)=%d]", GET_CODE (y));
730             break;
731           case MEM:
732             output_address (y);
733             fprintf (file, ",[mem:");
734             output_address (XEXP (x, 0));
735             fprintf (file, "] ;P_O_A plus");
736             break;
737           default:
738             fprintf (file, "P_O_A plus op1_UFO[code1=%d,code2=%d]",
739                      GET_CODE (x), GET_CODE (y));
740           }
741       }
742       break;
743     case CONST_INT:
744       if (INTVAL (addr) < 0x10000 && INTVAL (addr) >= -0x10000)
745         fprintf (file, "%d ; p_o_a const addr?!", INTVAL (addr));
746       else
747         {
748           fprintf (file, "[p_o_a=ILLEGAL_CONST]");
749           output_addr_const (file, addr);
750         }
751       break;
752     case LABEL_REF:
753     case SYMBOL_REF:
754       fprintf (file, "%s", XSTR (addr, 0));
755       break;
756     case MEM:
757       fprintf (file, "[memUFO:");
758       output_address (XEXP (addr, 0));
759       fprintf (file, "]");
760       break;
761     case CONST:
762       output_address (XEXP (addr, 0));
763       fprintf (file, " ;P_O_A const");
764       break;
765     case CODE_LABEL:
766       fprintf (file, "L%d", XINT (addr, 3));
767       break;
768     default:
769       fprintf (file, " p_o_a UFO, code=%d val=0x%x",
770                (int) GET_CODE (addr), INTVAL (addr));
771       break;
772     }
773 }
774