From: jeremy@legion.Corp.Sun.COM (Jeremy Allison)
Newsgroups: gnu.gcc.help
Subject: sun386i pic patch
Date: 18 Nov 92 23:54:06 GMT
Reply-To: Jeremy.Allison@Corp.Sun.COM
Organization: Sun Microsystems CTE Corporate Technical Escalations center

Jeremy Allison 11/18/92 (jeremy.allison@corp.sun.com)

I have created a patch that allows gcc-2.3.1 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.

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 have submitted this to the GNU project, but rms found the change to stmt.c
unacceptable. However, it does seem to work, I have compiled X11R5
successfully with these patches in place - so if you don't mind these not
being an officially blessed GNU patch.... go ahead !

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

********************* DISCLAIMER *****************************

NOTE THIS IS NOT A SUN SUPPLIED PATCH, I HAVE GENERATED IT IN MY SPARE
TIME. THIS IS NOT A SUN SUPPORTED POSTING. I WILL LOOK AT ANY PROBLEMS
PEOPLE MAY FIND BUT THIS IS BEING DONE IN MY SPARE TIME FOR MY OWN
PROJECTS (I own a 386i at home).


---------------diff for config/i386.c---------------------------------
% diff -c config/i386.c-orig config/i386.c
*** config/i386.c-orig  Mon Nov  2 16:31:52 1992
--- config/i386.c       Mon Nov  2 16:35:39 1992
***************
*** 579,587 ****
--- 579,589 ----
          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));
***************
*** 693,699 ****
--- 695,705 ----
        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
      }
  }
  
***************
*** 879,885 ****
--- 885,902 ----
          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");
***************
*** 887,892 ****
--- 904,910 ----
        fprintf (file, "@GOT");
        else
        fprintf (file, "@GOTOFF");
+ #endif
  
        break;


-------------context diff for config/i386.md-------------------
% diff -c config/i386.md-orig config/i386.md
*** config/i386.md-orig Mon Nov  2 16:28:00 1992
--- config/i386.md      Tue Nov 17 11:10:21 1992
***************
*** 867,873 ****
      return AS1 (fxch,%0);
  }")
  
! (define_insn "movdf"
    [(set (match_operand:DF 0 "general_operand" "=f,fm,!*rf,!*rm")
        (match_operand:DF 1 "general_operand" "fmG,f,*rfm,*rfF"))]
    ""
--- 867,888 ----
      return AS1 (fxch,%0);
  }")
  
! (define_expand "movdf"
!   [(set (match_operand:DF 0 "general_operand" "")
!         (match_operand:DF 1 "general_operand" ""))]
!   ""
!   " 
! {
!   extern int flag_pic;
! 
!   if (flag_pic && (GET_CODE(operands[1])== CONST_DOUBLE)) {
!       operands[1] = XEXP(force_const_mem( DFmode, operands[1]),0);
!       CONSTANT_POOL_ADDRESS_P(operands[1]) = 0; /* Cheat */
!       operands[1] = gen_rtx(MEM, DFmode, emit_pic_move(operands, SImode));
!   }
! }")
! 
! (define_insn ""
    [(set (match_operand:DF 0 "general_operand" "=f,fm,!*rf,!*rm")
        (match_operand:DF 1 "general_operand" "fmG,f,*rfm,*rfF"))]
    ""
***************
*** 3672,3678 ****
--- 3687,3697 ----
    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;

-----------------context diff for config/i386sun.h-----------

% diff -c config/i386sun.h-orig config/i386sun.h
*** config/i386sun.h-orig       Mon Nov  2 16:26:18 1992
--- config/i386sun.h    Mon Nov  2 16:27:12 1992
***************
*** 39,45 ****
  
  /* Extra switches to give the assembler.  */
  
! #define ASM_SPEC "-i386"
  
  /* Specify predefined symbols in preprocessor.  */
  
--- 39,45 ----
  
  /* Extra switches to give the assembler.  */
  
! #define ASM_SPEC "-i386 %{fpic:-k} %{fPIC:-k}"
  
  /* Specify predefined symbols in preprocessor.  */
  
***************
*** 64,69 ****
--- 64,73 ----
  /* We want to output DBX debugging information.  */
  
  #define DBX_DEBUGGING_INFO
+ 
+ /* DBX info should come _before_ the function for the 386i assembler and gdb */
+ 
+ #define DBX_FUNCTION_FIRST
  
  /* Implicit library calls should use memcpy, not bcopy, etc.  */

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

% diff -c stmt.c-orig stmt.c
*** stmt.c-orig Fri Oct  9 09:59:03 1992
--- stmt.c      Mon Nov  2 16:37:05 1992
***************
*** 3747,3752 ****
--- 3747,3755 ----
  #endif /* CASE_VALUES_THRESHOLD */
  
        else if (TREE_INT_CST_HIGH (range) != 0
+ #ifdef sun386
+              || flag_pic
+ #endif
               || count < CASE_VALUES_THRESHOLD
               || ((unsigned HOST_WIDE_INT) (TREE_INT_CST_LOW (range))
                   > 10 * count)
Newsgroups: gnu.gcc.help