Annotation of GNUtools/cc/machopic.c, revision 1.1.1.1

1.1       root        1: /* NeXTSTEP mach-o pic support functions.
                      2:    Copyright (C) 1992, 1994 Free Software Foundation, Inc.
                      3: 
                      4: This file is part of GNU CC.
                      5: 
                      6: GNU CC is free software; you can redistribute it and/or modify
                      7: it under the terms of the GNU General Public License as published by
                      8: the Free Software Foundation; either version 2, or (at your option)
                      9: any later version.
                     10: 
                     11: GNU CC is distributed in the hope that it will be useful,
                     12: but WITHOUT ANY WARRANTY; without even the implied warranty of
                     13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     14: GNU General Public License for more details.
                     15: 
                     16: You should have received a copy of the GNU General Public License
                     17: along with GNU CC; see the file COPYING.  If not, write to
                     18: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
                     19: 
                     20: /* 
                     21:  * flag_pic = 1 ... generate only indirections
                     22:  * flag_pic = 2 ... generate indirections and pure code
                     23:  */
                     24: 
                     25: 
                     26: /* 
                     27:  *   This module assumes that (const (symbol_ref "foo")) is
                     28:  *   a legal pic reference, which will not be changed.
                     29:  */
                     30: #include "config.h"
                     31: 
                     32: #ifdef MACHO_PIC
                     33: 
                     34: #include "tree.h"
                     35: #include "rtl.h"
                     36: #include "output.h"
                     37: #include "machopic.h"
                     38: #include "insn-config.h"
                     39: #include "insn-flags.h"
                     40: 
                     41: #include <stdio.h>
                     42: 
                     43: /* Answer if the symbol named IDENT is known to be defined in 
                     44:    the current module.  It is critical, that it *never* says
                     45:    something is defined, when it isn't.  However, it is ok to be 
                     46:    sloppy on the other end of the scale, it will only generate 
                     47:    worse code than if it guessed correct. */
                     48: 
                     49: static tree machopic_defined_list = 0;
                     50: 
                     51: extern int flag_dave_indirect;
                     52: 
                     53: enum machopic_addr_class
                     54: machopic_classify_ident (ident)
                     55:      tree ident;
                     56: {
                     57:   char *name = IDENTIFIER_POINTER (ident);
                     58:   int lprefix = (name[0] == '*' 
                     59:                 && (name[1] == 'L'
                     60:                     || (name[1] == '"' && name[2] == 'L'))); 
                     61:     
                     62:   tree temp, decl  = (tree)lookup_name (ident);
                     63: 
                     64:   if (!decl)
                     65:     {
                     66:       if (lprefix)
                     67:        {
                     68:          char *name = IDENTIFIER_POINTER (ident);
                     69:          while (*name++)
                     70:            {
                     71:              if (! strncmp (name, "$stub\0", 6))
                     72:                return MACHOPIC_DEFINED_FUNCTION;
                     73:            }
                     74:          return MACHOPIC_DEFINED_DATA;
                     75:        }
                     76: 
                     77:       for (temp = machopic_defined_list;
                     78:           temp != NULL_TREE; 
                     79:           temp = TREE_CHAIN (temp))
                     80:        {
                     81:          if (ident == TREE_VALUE (temp))
                     82:            return MACHOPIC_DEFINED_DATA;
                     83:        }
                     84: 
                     85:       return MACHOPIC_UNDEFINED;
                     86:     }
                     87: 
                     88:   /* variable declarations */
                     89:   else if (TREE_CODE (decl) == VAR_DECL)
                     90:     {
                     91:       if ((DECL_INITIAL (decl) 
                     92:           || TREE_STATIC (decl))
                     93:          && ! TREE_PUBLIC (decl))
                     94:        return MACHOPIC_DEFINED_DATA;
                     95:     }
                     96: 
                     97:   /* function declarations */
                     98:   else if (TREE_CODE (decl) == FUNCTION_DECL)
                     99:     {
                    100:       if (TREE_STATIC (decl)
                    101:          || TREE_ASM_WRITTEN (decl))
                    102:        return MACHOPIC_DEFINED_FUNCTION;
                    103:     }
                    104: 
                    105:   for (temp = machopic_defined_list;
                    106:        temp != NULL_TREE; 
                    107:        temp = TREE_CHAIN (temp))
                    108:     {
                    109:       if (ident == TREE_VALUE (temp))
                    110:        if (TREE_CODE (decl) == FUNCTION_DECL)
                    111:          return MACHOPIC_DEFINED_FUNCTION;
                    112:        else
                    113:          return MACHOPIC_DEFINED_DATA;
                    114:     }
                    115:   
                    116:   if (TREE_CODE (decl) == FUNCTION_DECL)
                    117:     {
                    118:       if (lprefix)
                    119:        return MACHOPIC_DEFINED_FUNCTION;
                    120:       else
                    121:        return MACHOPIC_UNDEFINED_FUNCTION;
                    122:     }
                    123:   else
                    124:     {
                    125:       if (lprefix)
                    126:        return MACHOPIC_DEFINED_DATA;
                    127:       else
                    128:        return MACHOPIC_UNDEFINED_DATA;
                    129:     }
                    130: }
                    131: 
                    132:      
                    133: enum machopic_addr_class
                    134: machopic_classify_name (name)
                    135:      char *name;
                    136: {
                    137:   return machopic_classify_ident (get_identifier (name));
                    138: }
                    139: 
                    140: int
                    141: machopic_ident_defined_p (ident)
                    142:      tree ident;
                    143: {
                    144:   switch (machopic_classify_ident (ident))
                    145:     {
                    146:     case MACHOPIC_UNDEFINED:
                    147:     case MACHOPIC_UNDEFINED_DATA:
                    148:     case MACHOPIC_UNDEFINED_FUNCTION:
                    149:       return 0;
                    150:     default:
                    151:       return 1;
                    152:     }
                    153: }
                    154: 
                    155: int
                    156: machopic_name_defined_p (name)
                    157:      char *name;
                    158: {
                    159:   return machopic_ident_defined_p (get_identifier (name));
                    160: }
                    161: 
                    162: void
                    163: machopic_define_ident (ident)
                    164:      tree ident;
                    165: {
                    166:   if (!machopic_ident_defined_p (ident))
                    167:     machopic_defined_list = 
                    168:       perm_tree_cons (NULL_TREE, ident, machopic_defined_list);
                    169: }
                    170: 
                    171: void
                    172: machopic_define_name (name)
                    173:      char *name;
                    174: {
                    175:   machopic_define_ident (get_identifier (name));
                    176: }
                    177: 
                    178: /* This is a static to make inline functions work.  The rtx */
                    179: /* representing the PIC base symbol allways points to here. */
                    180: static char function_base[256];
                    181: 
                    182: char*
                    183: machopic_function_base_name ()
                    184: {
                    185:   static char *name = 0, *curr_name;
                    186:   static int base = 0;
                    187: 
                    188:   curr_name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl));
                    189: 
                    190:   if (name != curr_name)
                    191:     {
                    192:       current_function_uses_pic_offset_table = 1;
                    193: 
                    194:       if (strchr (curr_name, ' '))
                    195:        sprintf (function_base, "*\"L%s$pic_base\"", curr_name);
                    196:       else
                    197:        sprintf (function_base, "*L%s$pic_base", curr_name);
                    198: 
                    199:       name = curr_name;
                    200:     }
                    201: 
                    202:   return function_base;
                    203: }
                    204: 
                    205: static tree machopic_non_lazy_pointers = 0;
                    206: 
                    207: char* 
                    208: machopic_non_lazy_ptr_name (name)
                    209:      char *name;
                    210: {
                    211:   tree temp, ident = get_identifier (name);
                    212:   
                    213:   for (temp = machopic_non_lazy_pointers;
                    214:        temp != NULL_TREE; 
                    215:        temp = TREE_CHAIN (temp))
                    216:     {
                    217:       if (ident == TREE_VALUE (temp))
                    218:        return IDENTIFIER_POINTER (TREE_PURPOSE (temp));
                    219:     }
                    220: 
                    221:   {
                    222:     char buffer[256];
                    223:     tree ptr_name;
                    224: 
                    225:     strcpy (buffer, "*L");
                    226:     if (name[0] == '*')
                    227:       strcat (buffer, name+1);
                    228:     else
                    229:       {
                    230:        strcat (buffer, "_");
                    231:        strcat (buffer, name);
                    232:       }
                    233:       
                    234:     strcat (buffer, "$non_lazy_ptr");
                    235:     ptr_name = get_identifier (buffer);
                    236: 
                    237:     machopic_non_lazy_pointers 
                    238:       = perm_tree_cons (ptr_name, ident, machopic_non_lazy_pointers);
                    239: 
                    240:     return IDENTIFIER_POINTER (ptr_name);
                    241:   }
                    242: }
                    243: 
                    244: static tree machopic_stubs = 0;
                    245: 
                    246: char* 
                    247: machopic_stub_name (name)
                    248:      char *name;
                    249: {
                    250:   tree temp, ident = get_identifier (name);
                    251:   
                    252:   for (temp = machopic_stubs;
                    253:        temp != NULL_TREE; 
                    254:        temp = TREE_CHAIN (temp))
                    255:     {
                    256:       if (ident == TREE_VALUE (temp))
                    257:        return IDENTIFIER_POINTER (TREE_PURPOSE (temp));
                    258:     }
                    259: 
                    260:   {
                    261:     char buffer[256];
                    262:     tree ptr_name;
                    263: 
                    264:     strcpy (buffer, "*L");
                    265:     if (name[0] == '*')
                    266:       {
                    267:        strcat (buffer, name+1);
                    268:       }
                    269:     else
                    270:       {
                    271:        strcat (buffer, "_");
                    272:        strcat (buffer, name);
                    273:       }
                    274: 
                    275:     strcat (buffer, "$stub");
                    276:     ptr_name = get_identifier (buffer);
                    277: 
                    278:     machopic_stubs = perm_tree_cons (ptr_name, ident, machopic_stubs);
                    279: 
                    280:     return IDENTIFIER_POINTER (ptr_name);
                    281:   }
                    282: }
                    283: 
                    284: /*
                    285:  *  Transfrom ORIG, which any data source to the corresponding
                    286:  *  source using indirections.  
                    287:  */
                    288: 
                    289: rtx
                    290: machopic_indirect_data_reference (orig, reg)
                    291:      rtx orig, reg;
                    292: {
                    293:   rtx ptr_ref = orig;
                    294:   
                    295:   if (! MACHOPIC_INDIRECT)
                    296:     return orig;
                    297: 
                    298:   if (GET_CODE (orig) == SYMBOL_REF)
                    299:     {
                    300:       char *name = XSTR (orig, 0);
                    301: 
                    302:       if (machopic_name_defined_p (name))
                    303:        {
                    304: #ifdef HAVE_hi_sum
                    305:          rtx hi_sum;
                    306:          rtx pic_base = gen_rtx (SYMBOL_REF, Pmode, 
                    307:                                   machopic_function_base_name ());
                    308:          rtx offset = gen_rtx (CONST, Pmode, gen_rtx (MINUS, Pmode, orig, pic_base));
                    309: 
                    310: 
                    311:          if (reg == 0) abort ();
                    312: 
                    313:          hi_sum = gen_rtx (SET, Pmode, HI_SUM_TARGET_RTX,
                    314:                            gen_rtx (PLUS, Pmode,
                    315:                                     pic_offset_table_rtx,
                    316:                                     gen_rtx (HIGH, Pmode, offset)));
                    317: 
                    318: #if 1
                    319:          emit_insn (hi_sum);
                    320: #else
                    321:          emit_insn (gen_rtx (PARALLEL, VOIDmode,
                    322:                              gen_rtvec (2,
                    323:                                         hi_sum,
                    324:                                         gen_rtx (USE, VOIDmode,
                    325:                                                  gen_rtx (REG, Pmode, PIC_OFFSET_TABLE_REGNUM)))));
                    326: #endif
                    327:          
                    328:          emit_insn (gen_rtx (SET, Pmode, reg,
                    329:                              gen_rtx (LO_SUM, Pmode, 
                    330:                                       HI_SUM_TARGET_RTX, 
                    331:                                       offset)));
                    332: 
                    333:          {
                    334:            rtx insn = get_last_insn ();
                    335:            rtx note = find_reg_note (insn, REG_EQUAL, NULL_RTX);
                    336:            
                    337:            if (note)
                    338:              XEXP (note, 0) = orig;
                    339:            else
                    340:              REG_NOTES (insn) = gen_rtx (EXPR_LIST, 
                    341:                                          REG_EQUAL, orig, REG_NOTES (insn));
                    342:          }
                    343: 
                    344:          orig = reg;
                    345: #else
                    346: #ifdef HAVE_lo_sum
                    347:          rtx pic_base = gen_rtx (SYMBOL_REF, Pmode, 
                    348:                                   machopic_function_base_name ());
                    349: 
                    350:          if (reg == 0) abort ();
                    351: 
                    352:          emit_insn (gen_rtx (SET, VOIDmode, reg,
                    353:                              gen_rtx (HIGH, Pmode, 
                    354:                                       gen_rtx (CONST, Pmode, 
                    355:                                                gen_rtx (MINUS, Pmode,
                    356:                                                         orig, pic_base)))));
                    357:          emit_insn (gen_rtx (SET, VOIDmode, reg,
                    358:                              gen_rtx (LO_SUM, Pmode, reg, 
                    359:                                       gen_rtx (CONST, Pmode, 
                    360:                                                gen_rtx (MINUS, Pmode,
                    361:                                                         orig, pic_base)))));
                    362:          emit_insn (gen_rtx (USE, VOIDmode,
                    363:                              gen_rtx (REG, Pmode, PIC_OFFSET_TABLE_REGNUM)));
                    364: 
                    365:          orig = gen_rtx (PLUS, Pmode, pic_offset_table_rtx, reg);
                    366: #endif
                    367: #endif
                    368:          return orig;
                    369:        }
                    370: 
                    371: 
                    372:       if (flag_dave_indirect) 
                    373:        {
                    374:          extern tree string_type_node;
                    375:          extern tree char_array_type_node;
                    376:          tree params;
                    377:          tree call;
                    378:          tree get_addr_decl;
                    379: 
                    380:          if (reg == 0)
                    381:            reg = gen_reg_rtx (Pmode);
                    382: 
                    383:          get_addr_decl 
                    384:            = (tree) lookup_name (get_identifier ("__get_address"));   
                    385:          if (get_addr_decl == 0)
                    386:            error ("cannot find declaration for __get_address");
                    387: 
                    388:          params = build_string (strlen (name), name);
                    389:          TREE_TYPE (params) = char_array_type_node;
                    390:          params = build1 (ADDR_EXPR, string_type_node, params);
                    391:          params = build_tree_list (NULL_TREE, params);
                    392: 
                    393:          call = (tree) build_function_call (get_addr_decl, params);
                    394:          expand_call (call, reg, 0);
                    395:          RTX_UNCHANGING_P (reg) = 1;
                    396:          return reg;
                    397:        }
                    398:       else /* kevin_indirect */
                    399:        {
                    400:          ptr_ref = gen_rtx (SYMBOL_REF, Pmode, 
                    401:                             machopic_non_lazy_ptr_name (name));
                    402: 
                    403: 
                    404:          /* generating real pure code */
                    405: /*
                    406:          if (MACHOPIC_PURE)
                    407:            ptr_ref = machopic_legitimize_pic_address (ptr_ref, SImode, reg);
                    408:        */  
                    409:          ptr_ref = gen_rtx (MEM, Pmode, ptr_ref);
                    410:          RTX_UNCHANGING_P (ptr_ref) = 1;
                    411:        }
                    412: 
                    413:       return ptr_ref;
                    414:     }
                    415:   else if (GET_CODE (orig) == CONST)
                    416:     {
                    417:       rtx base, offset, result;
                    418: 
                    419:       /* legitimize both operands of the PLUS */
                    420:       if (GET_CODE (XEXP (orig, 0)) == PLUS)
                    421:        {
                    422:          base = machopic_indirect_data_reference (XEXP (XEXP (orig, 0), 0), reg);
                    423:          orig = machopic_indirect_data_reference (XEXP (XEXP (orig, 0), 1),
                    424:                                                   base == reg ? 0 : reg);
                    425:        }
                    426:       else 
                    427:        return orig;
                    428: 
                    429:       if (MACHOPIC_PURE && GET_CODE (orig) == CONST_INT)
                    430:        result = plus_constant_for_output (base, INTVAL (orig));
                    431:       else
                    432:        result = gen_rtx (PLUS, Pmode, base, orig);
                    433: 
                    434:       if (RTX_UNCHANGING_P (base) && RTX_UNCHANGING_P (orig))
                    435:        RTX_UNCHANGING_P (result) = 1;
                    436: 
                    437:       if (MACHOPIC_JUST_INDIRECT && GET_CODE (base) == MEM)
                    438:        {
                    439:          if (reg)
                    440:            {
                    441:              emit_move_insn (reg, result);
                    442:              result = reg;
                    443:            }
                    444:          else
                    445:            {
                    446:              result = force_reg (GET_MODE (result), result);
                    447:            }
                    448:        }
                    449: 
                    450:       return result;
                    451: 
                    452:     }
                    453:   else if (GET_CODE (orig) == MEM)
                    454:     {
                    455:       XEXP (ptr_ref, 0) = machopic_indirect_data_reference (XEXP (orig, 0), reg);
                    456:       return ptr_ref;
                    457:     }
                    458:   else
                    459:     return ptr_ref;
                    460: }
                    461: 
                    462: 
                    463: /* 
                    464:  *  Transform TARGET (a MEM), which is a function call target, to the
                    465:  *  corresponding symbol_stub if nessecary.  Return the a new MEM.
                    466:  */
                    467: 
                    468: rtx
                    469: machopic_indirect_call_target (target)
                    470:      rtx target;
                    471: {
                    472:   if (GET_CODE (target) != MEM)
                    473:     return target;
                    474:   if (MACHOPIC_INDIRECT && GET_CODE (XEXP (target, 0)) == SYMBOL_REF)
                    475:     { 
                    476:       enum machine_mode mode = GET_MODE (XEXP (target, 0));
                    477:       char *name = XSTR (XEXP (target, 0), 0);
                    478:       if (!machopic_name_defined_p (name)) 
                    479:        {
                    480:          if (flag_dave_indirect) 
                    481:            {
                    482:              XEXP (target, 0) = force_reg (Pmode, XEXP (target, 0));
                    483:            }
                    484:          else /* kevin_indirect */
                    485:            {
                    486:              char *stub_name = (char*)machopic_stub_name (name);
                    487:              XEXP (target, 0) = gen_rtx (SYMBOL_REF, mode, stub_name);
                    488:              RTX_UNCHANGING_P (target) = 1;
                    489:            }
                    490:        } 
                    491:     }
                    492:   return target;
                    493: }
                    494: 
                    495: 
                    496: rtx
                    497: machopic_legitimize_pic_address (orig, mode, reg)
                    498:      rtx orig, reg;
                    499:      enum machine_mode mode;
                    500: {
                    501:   rtx pic_ref = orig;
                    502: 
                    503:   if (! MACHOPIC_PURE)
                    504:     return orig;
                    505: 
                    506:   /* First handle a simple SYMBOL_REF or LABEL_REF */
                    507:   if (GET_CODE (orig) == LABEL_REF
                    508:       || (GET_CODE (orig) == SYMBOL_REF
                    509: #if 0
                    510:          && !((machopic_classify_name (XSTR (orig, 0)) 
                    511:                == MACHOPIC_DEFINED_FUNCTION)
                    512:               && XSTR (orig, 0)[0] == '*')
                    513: #endif
                    514:          ))
                    515:     {
                    516:       /* addr(foo) = &func+(foo-func) */
                    517:       rtx equiv = orig;
                    518:       rtx pic_base;
                    519:       orig = machopic_indirect_data_reference (orig, reg);
                    520:       if (GET_CODE (orig) == PLUS 
                    521:          && GET_CODE (XEXP (orig, 0)) == REG)
                    522:        {
                    523:          if (reg == 0)
                    524:            return force_reg (mode, orig);
                    525: 
                    526:          emit_move_insn (reg, orig);
                    527:          return reg;
                    528:        }  
                    529: 
                    530:       pic_base = gen_rtx (SYMBOL_REF, Pmode, 
                    531:                          machopic_function_base_name ());
                    532: 
                    533:       if (GET_CODE (orig) == MEM)
                    534:        {
                    535:          if (reg == 0)
                    536:            abort ();
                    537: #ifdef HAVE_lo_sum
                    538:          if (GET_CODE (XEXP (orig, 0)) == SYMBOL_REF 
                    539:              || GET_CODE (XEXP (orig, 0)) == LABEL_REF)
                    540:            {
                    541: #ifdef HAVE_hi_sum
                    542:              rtx hi_sum;
                    543:              rtx offset = gen_rtx (CONST, Pmode,
                    544:                                    gen_rtx (MINUS, Pmode, XEXP (orig, 0), pic_base));
                    545:              
                    546:              
                    547:              if (reg == 0)
                    548:                if (reload_in_progress)
                    549:                  abort ();
                    550:                else
                    551:                 reg = gen_reg_rtx (Pmode);
                    552:              
                    553:              hi_sum = gen_rtx (SET, Pmode, HI_SUM_TARGET_RTX,
                    554:                                gen_rtx (PLUS, Pmode,
                    555:                                         pic_offset_table_rtx,
                    556:                                         gen_rtx (HIGH, Pmode, offset)));
                    557: 
                    558: #if 1
                    559:              emit_insn (hi_sum);
                    560: #else
                    561:              emit_insn (gen_rtx (PARALLEL, VOIDmode,
                    562:                                  gen_rtvec (2,
                    563:                                             hi_sum,
                    564:                                             gen_rtx (USE, VOIDmode,
                    565:                                                      gen_rtx (REG, Pmode, PIC_OFFSET_TABLE_REGNUM)))));
                    566: #endif
                    567:              emit_insn (gen_rtx (SET, VOIDmode, reg,
                    568:                                  gen_rtx (MEM, GET_MODE (orig),
                    569:                                           gen_rtx (LO_SUM, Pmode, 
                    570:                                                    HI_SUM_TARGET_RTX, 
                    571:                                                    offset))));
                    572:              pic_ref = reg;
                    573: 
                    574: #else
                    575:              emit_insn (gen_rtx (USE, VOIDmode,
                    576:                                  gen_rtx (REG, Pmode, PIC_OFFSET_TABLE_REGNUM)));
                    577: 
                    578:              emit_insn (gen_rtx (SET, VOIDmode, reg,
                    579:                                  gen_rtx (HIGH, Pmode, 
                    580:                                           gen_rtx (CONST, Pmode, 
                    581:                                                    gen_rtx (MINUS, Pmode,
                    582:                                                             XEXP (orig, 0), 
                    583:                                                             pic_base)))));
                    584:              emit_insn (gen_rtx (SET, VOIDmode, reg,
                    585:                                  gen_rtx (LO_SUM, Pmode, reg, 
                    586:                                           gen_rtx (CONST, Pmode, 
                    587:                                                    gen_rtx (MINUS, Pmode,
                    588:                                                             XEXP (orig, 0), 
                    589:                                                             pic_base)))));
                    590:              pic_ref = gen_rtx (PLUS, Pmode,
                    591:                                 pic_offset_table_rtx, reg);
                    592: #endif
                    593:            }
                    594:          else
                    595: #endif
                    596:            {
                    597:              emit_insn (gen_rtx (USE, VOIDmode,
                    598:                                  gen_rtx (REG, Pmode, PIC_OFFSET_TABLE_REGNUM)));
                    599: 
                    600:              pic_ref = gen_rtx (PLUS, Pmode,
                    601:                                 pic_offset_table_rtx, 
                    602:                                 gen_rtx (CONST, Pmode, 
                    603:                                          gen_rtx (MINUS, Pmode,
                    604:                                                   XEXP (orig, 0), 
                    605:                                                   pic_base)));
                    606:            }
                    607:          
                    608: #ifndef HAVE_hi_sum
                    609:          RTX_UNCHANGING_P (pic_ref) = 1;
                    610:          emit_move_insn (reg, pic_ref);
                    611:          pic_ref = gen_rtx (MEM, GET_MODE (orig), reg);
                    612: #endif
                    613:        }
                    614:       else
                    615:        {
                    616: 
                    617: #ifdef HAVE_lo_sum
                    618:          if (GET_CODE (orig) == SYMBOL_REF 
                    619:              || GET_CODE (orig) == LABEL_REF)
                    620:            {
                    621: #ifdef HAVE_hi_sum
                    622:              rtx hi_sum;
                    623:              rtx offset = gen_rtx (CONST, Pmode,
                    624:                                    gen_rtx (MINUS, Pmode, orig, pic_base));
                    625:              
                    626:              if (reg == 0)
                    627:                if (reload_in_progress)
                    628:                  abort ();
                    629:                else
                    630:                 reg = gen_reg_rtx (SImode);
                    631:              
                    632:              hi_sum = gen_rtx (SET, Pmode, HI_SUM_TARGET_RTX,
                    633:                                gen_rtx (PLUS, Pmode,
                    634:                                         pic_offset_table_rtx,
                    635:                                         gen_rtx (HIGH, Pmode, offset)));
                    636: 
                    637: #if 1
                    638:              emit_insn (hi_sum);
                    639: #else
                    640:              emit_insn (gen_rtx (PARALLEL, VOIDmode,
                    641:                                  gen_rtvec (2,
                    642:                                             hi_sum,
                    643:                                             gen_rtx (USE, VOIDmode,
                    644:                                                      gen_rtx (REG, Pmode, PIC_OFFSET_TABLE_REGNUM)))));
                    645: #endif
                    646:              emit_insn (gen_rtx (SET, VOIDmode, reg,
                    647:                                  gen_rtx (LO_SUM, Pmode, 
                    648:                                           HI_SUM_TARGET_RTX, 
                    649:                                           offset)));
                    650:              pic_ref = reg;
                    651: #else
                    652:              emit_insn (gen_rtx (SET, VOIDmode, reg,
                    653:                                  gen_rtx (HIGH, Pmode, 
                    654:                                           gen_rtx (CONST, Pmode, 
                    655:                                                    gen_rtx (MINUS, Pmode,
                    656:                                                             orig, pic_base)))));
                    657:              emit_insn (gen_rtx (SET, VOIDmode, reg,
                    658:                                  gen_rtx (LO_SUM, Pmode, reg, 
                    659:                                           gen_rtx (CONST, Pmode, 
                    660:                                                    gen_rtx (MINUS, Pmode,
                    661:                                                             orig, pic_base)))));
                    662:              pic_ref = gen_rtx (PLUS, Pmode,
                    663:                                 pic_offset_table_rtx, reg);
                    664: #endif
                    665:            }
                    666:          else
                    667: #endif
                    668:            if (GET_CODE (orig) == REG)
                    669:              {
                    670:                return orig;
                    671:              }
                    672:            else
                    673:              {
                    674:                emit_insn (gen_rtx (USE, VOIDmode,
                    675:                                    gen_rtx (REG, Pmode, PIC_OFFSET_TABLE_REGNUM)));
                    676: 
                    677:                pic_ref = gen_rtx (PLUS, Pmode,
                    678:                                   pic_offset_table_rtx, 
                    679:                                   gen_rtx (CONST, Pmode, 
                    680:                                            gen_rtx (MINUS, Pmode,
                    681:                                                     orig, pic_base)));
                    682:              }
                    683:        }
                    684: 
                    685:       RTX_UNCHANGING_P (pic_ref) = 1;
                    686: 
                    687:       if (reg == 0)
                    688:        return force_reg (mode, pic_ref);
                    689:       else
                    690:        {
                    691:          if (GET_CODE (pic_ref) != REG)
                    692:            emit_move_insn (reg, pic_ref);
                    693:          else
                    694:            reg = pic_ref;
                    695: 
                    696:          {
                    697:            rtx insn = get_last_insn ();
                    698:            rtx note = find_reg_note (insn, REG_EQUAL, NULL_RTX);
                    699:            
                    700:            if (note)
                    701:              XEXP (note, 0) = equiv;
                    702:            else
                    703:              REG_NOTES (insn) = gen_rtx (EXPR_LIST, 
                    704:                                          REG_EQUAL, equiv, REG_NOTES (insn));
                    705:          }
                    706: 
                    707:          return reg;
                    708:        }
                    709:     }
                    710: 
                    711:   else if (GET_CODE (orig) == SYMBOL_REF)
                    712:     return orig;
                    713: 
                    714:   else if (GET_CODE (orig) == PLUS
                    715:           && (GET_CODE (XEXP (orig, 0)) == MEM
                    716:               || GET_CODE (XEXP (orig, 0)) == SYMBOL_REF
                    717:               || GET_CODE (XEXP (orig, 0)) == LABEL_REF)
                    718:           && XEXP (orig, 0) != pic_offset_table_rtx
                    719:           && GET_CODE (XEXP (orig, 1)) != REG)
                    720:     
                    721:     {
                    722:       rtx base, offset;
                    723:       int is_complex;
                    724: 
                    725:       is_complex = (GET_CODE (XEXP (orig, 0)) == MEM);
                    726: 
                    727:       base = machopic_legitimize_pic_address (XEXP (orig, 0), Pmode, reg);
                    728:       orig = machopic_legitimize_pic_address (XEXP (orig, 1),
                    729:                                              Pmode, base == reg ? 0 : reg);
                    730:       if (GET_CODE (orig) == CONST_INT)
                    731:        {
                    732:          pic_ref = plus_constant_for_output (base, INTVAL (orig));
                    733:          is_complex = 1;
                    734:        }
                    735:       else
                    736:        {
                    737:          pic_ref = gen_rtx (PLUS, Pmode, base, orig);
                    738:        }
                    739: 
                    740:       if (RTX_UNCHANGING_P (base) && RTX_UNCHANGING_P (orig))
                    741:        RTX_UNCHANGING_P (pic_ref) = 1;
                    742: 
                    743:       if (reg && is_complex)
                    744:        {
                    745:          emit_move_insn (reg, pic_ref);
                    746:          pic_ref = reg;
                    747:        }
                    748:       /* Likewise, should we set special REG_NOTEs here?  */
                    749:     }
                    750: 
                    751:   else if (GET_CODE (orig) == CONST)
                    752:     {
                    753:       return machopic_legitimize_pic_address (XEXP (orig, 0), Pmode, reg);
                    754:     }
                    755: 
                    756:   else if (GET_CODE (orig) == MEM
                    757:           && GET_CODE (XEXP (orig, 0)) == SYMBOL_REF)
                    758:     {
                    759:       rtx addr = machopic_legitimize_pic_address (XEXP (orig, 0), Pmode, reg);
                    760: 
                    761:       emit_move_insn (reg, gen_rtx (MEM, GET_MODE (orig), addr));
                    762:       pic_ref = reg;
                    763:     }
                    764: 
                    765:   return pic_ref;
                    766: }
                    767: 
                    768: 
                    769: void
                    770: machopic_finish (asm_out_file)
                    771:      FILE *asm_out_file;
                    772: {
                    773:   tree temp;
                    774: 
                    775:   for (temp = machopic_stubs;
                    776:        temp != NULL_TREE; 
                    777:        temp = TREE_CHAIN (temp))
                    778:     {
                    779:       char symb[256];
                    780:       char stub[256];
                    781:       char *symb_name = IDENTIFIER_POINTER (TREE_VALUE (temp));
                    782:       char *stub_name = IDENTIFIER_POINTER (TREE_PURPOSE (temp));
                    783:       
                    784:       if (symb_name[0] == '*')
                    785:        strcpy (symb, symb_name+1);
                    786:       else
                    787:        symb[0] = '_', strcpy (symb+1, symb_name);
                    788: 
                    789:       if (stub_name[0] == '*')
                    790:        strcpy (stub, stub_name+1);
                    791:       else
                    792:        stub[0] = '_', strcpy (stub+1, stub_name);
                    793: 
                    794:       /* must be in aux-out.c */
                    795:       machopic_output_stub (asm_out_file, symb, stub);
                    796:          
                    797:     }
                    798: 
                    799:   for (temp = machopic_non_lazy_pointers;
                    800:        temp != NULL_TREE; 
                    801:        temp = TREE_CHAIN (temp))
                    802:     {
                    803:       char *symb_name = IDENTIFIER_POINTER (TREE_VALUE (temp));
                    804:       char *lazy_name = IDENTIFIER_POINTER (TREE_PURPOSE (temp));
                    805: 
                    806: 
                    807:       if (machopic_ident_defined_p (TREE_VALUE (temp))) 
                    808:        {
                    809:          char symb[256];
                    810:          
                    811:          if (symb_name[0] == '*')
                    812:            strcpy (symb, symb_name+1);
                    813:          else
                    814:            strcpy (symb, symb_name);
                    815: 
                    816:          readonly_data_section ();
                    817:          assemble_label (lazy_name);
                    818:          assemble_integer (gen_rtx (SYMBOL_REF, Pmode, symb_name),
                    819:                            GET_MODE_SIZE (Pmode), 1);
                    820:        }
                    821:       else
                    822:        {
                    823:          machopic_nl_symbol_ptr_section ();
                    824:          assemble_name (asm_out_file, lazy_name); 
                    825:          fprintf (asm_out_file, ":\n");
                    826: 
                    827:          fprintf (asm_out_file, "\t.indirect_symbol ");
                    828:          assemble_name (asm_out_file, symb_name); 
                    829:          fprintf (asm_out_file, "\n");
                    830: 
                    831:          assemble_integer (const0_rtx, GET_MODE_SIZE (Pmode), 1);
                    832:        }
                    833:     }
                    834: }
                    835: 
                    836: int 
                    837: machopic_operand_p (op)
                    838:      rtx op;
                    839: {
                    840:   if (MACHOPIC_JUST_INDIRECT)
                    841:     {
                    842:       while (GET_CODE (op) == CONST)
                    843:        op = XEXP (op, 0);
                    844: 
                    845:       if (GET_CODE (op) == SYMBOL_REF)
                    846:        return machopic_name_defined_p (XSTR (op, 0));
                    847:       else
                    848:        return 0;
                    849:     }
                    850: 
                    851:   while (GET_CODE (op) == CONST)
                    852:     op = XEXP (op, 0);
                    853: 
                    854:   if (GET_CODE (op) == MINUS
                    855:           && GET_CODE (XEXP (op, 0)) == SYMBOL_REF
                    856:           && GET_CODE (XEXP (op, 1)) == SYMBOL_REF
                    857:           && machopic_name_defined_p (XSTR (XEXP (op, 0), 0))
                    858:           && machopic_name_defined_p (XSTR (XEXP (op, 1), 0)))
                    859:     {
                    860:       return 1;
                    861:     }
                    862: 
                    863: #if 0
                    864:   else if (GET_CODE (op) == SYMBOL_REF
                    865:           && (machopic_classify_name (XSTR (op, 0))
                    866:               == MACHOPIC_DEFINED_FUNCTION))
                    867:     {
                    868:       return 1;
                    869:     }
                    870: #endif
                    871: 
                    872:   return 0;
                    873: }
                    874: 
                    875: #endif
                    876: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.