From: Jeremy.Allison@corp.SUn.COM (Jeremy Allison)
Subject: Sun386i Patch for position independent code in gcc-2.2.2
Organization: GNUs Not Usenet
Distribution: gnu
Date: Thu, 13 Aug 1992 18:33:52 GMT

Jeremy Allison 8/13/92 (jeremy.allison@corp.sun.com)

I have created a patch that allows gcc-2.2.2 to produce position
independent code on a Sun386i under 4.0.2. The patch only works if the sun
assembler is used rather than gas, as gas does not handle pic code (I
looked into patching gas to support pic code but it was more work than I
had time for, sorry.).

Most of the changes I have made are in the config directory, to the files 

i386.c, i386.md, i386sun.h

but I had to make one change to stmt.c for the following reason. When gcc
generates switch statements it can generate code that tests each case in
turn (comparison code), or produces a table of offsets as a jump table.
When operating in pic code mode, the sun assembler cannot handle these jump
tables, so I added an #ifdef that forced comparison code to be generated if
the machine is a sun386i and if pic code was requested. I hope this will be
acceptable.

The context diffs follow, where the original files are <filename>-orig.

-------diff to config/i386.c--------------

%diff -c config/i386.c-orig config/i386.c
*** config/i386.c-orig Thu Jul  9 09:11:43 1992
--- config/i386.c      Mon Jul 27 09:08:47 1992
***************
*** 549,557 ****
--- 549,559 ----
          if (reg == 0)
            reg = gen_reg_rtx (Pmode);
  
+ #ifndef sun386
          if (GET_CODE (addr) == SYMBOL_REF && SYMBOL_REF_FLAG (addr))
            new = gen_rtx (PLUS, Pmode, pic_offset_table_rtx, orig);
          else
+ #endif
            new = gen_rtx (MEM, Pmode,
                           gen_rtx (PLUS, Pmode,
                                    pic_offset_table_rtx, orig));
***************
*** 662,668 ****
--- 664,674 ----
        output_asm_insn (AS1 (call,%P1), xops);
        ASM_OUTPUT_INTERNAL_LABEL (file, "L", CODE_LABEL_NUMBER (xops[1]));
        output_asm_insn (AS1 (pop%L0,%0), xops);
+ #ifdef sun386
+       output_asm_insn ("addl $_globtb_offset,%0", xops);
+ #else
        output_asm_insn ("addl $_GLOBAL_OFFSET_TABLE_+[.-%P1],%0", xops);
+ #endif
      }
  }
  
***************
*** 848,854 ****
--- 854,871 ----
          assemble_name (asm_out_file, buf);
        }
  
+ #ifdef sun386
        if (GET_CODE (x) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (x))
+       fprintf (file, "(%%ebx)");
+       else if (code == 'P')
+       fprintf (file, ", %%eax"); /* Needed for stupid sun386i assembler to
+                                     generate pic reference */
+       else if (GET_CODE (x) == LABEL_REF || ! SYMBOL_REF_FLAG (x))
+       ;
+       else
+       ;
+ #else
+       if (GET_CODE (x) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (x))
        fprintf (file, "@GOTOFF(%%ebx)");
        else if (code == 'P')
        fprintf (file, "@PLT");
***************
*** 856,861 ****
--- 873,879 ----
        fprintf (file, "@GOT");
        else
        fprintf (file, "@GOTOFF");
+ #endif
  
        break;
-------------------------end diff for config/i386.c----------------------

--------------diff for config/i386.md------------------------------------

% diff -c config/i386.md-orig config/i386.md
*** config/i386.md-orig        Thu Jul  9 09:11:32 1992
--- config/i386.md     Mon Jul 27 09:08:33 1992
***************
*** 3568,3574 ****
--- 3568,3578 ----
    xops[3] = pic_offset_table_rtx;
  
    output_asm_insn (AS2 (mov%L2,%3,%2), xops);
+ #ifdef sun386
+   output_asm_insn (\"sub%L2 %l1(%3,%0,4),%2\", xops);
+ #else
    output_asm_insn (\"sub%L2 %l1@GOTOFF(%3,%0,4),%2\", xops);
+ #endif
    output_asm_insn (AS1 (jmp,%*%2), xops);
    ASM_OUTPUT_ALIGN_CODE (asm_out_file);
    RET;
-------end diff of config/i386.md-------------------------------

-------diff of config/i386sun.h----------------------------------------

% diff -c config/i386sun.h-orig config/i386sun.h
*** config/i386sun.h-orig      Mon Jul 27 09:11:02 1992
--- config/i386sun.h   Mon Jul 27 09:20:33 1992
***************
*** 42,48 ****
  
  /* Extra switches to give the assembler.  */
  
! #define ASM_SPEC "-i386"
  
  /* Specify predefined symbols in preprocessor.  */
  
--- 42,48 ----
  
  /* Extra switches to give the assembler.  */
  
! #define ASM_SPEC "-i386 %{fpic:-k} %{fPIC:-k}"
  
  /* Specify predefined symbols in preprocessor.  */
  
---------end of diff for config/i386sun.h---------------------

----------diff for stmt.c-------------------------------------

% diff -c stmt.c-orig stmt.c
*** stmt.c-orig Wed Jul 29 12:44:34 1992
--- stmt.c      Wed Jul 29 13:17:30 1992
***************
*** 3602,3607 ****
--- 3602,3610 ----
         If the switch-index is a constant, do it this way
         because we can optimize it.  */
        else if (TREE_INT_CST_HIGH (range) != 0
+ #ifdef sun386
+               || flag_pic
+ #endif
  #ifdef HAVE_casesi
               || (HAVE_casesi ? count < 4 : count < 5)
  #else
-------end of diff for stmt.c----------------------------

Newsgroups: gnu.gcc.bug