Annotation of GNUtools/cc/machopic.c, revision 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.