Fix Thumb pic_load_addr

Nick Clifton nickc@redhat.com
Tue Nov 28 17:44:00 GMT 2000


Hi Guys,

  Building libstd++-v3 for the Thumb currently falls over because the
  pic_load_addr pattern is producing an ARM style LDR instruction
  (with a conditional field) and accepting High registers as well.
  The patch below fixes this, possibly not in the neatest way, but it
  works, so I will be checking it in.

Cheers
	Nick

2000-11-28  Nick Clifton  <nickc@redhat.com>

	* config/arm/arm.md (pic_load_addr): Split into
	pic_load_addr_arm and pic_load_addr_thumb.

	* config/arm/arm.c (legitimize_pic_address): Generate either
	ARM or Thumb versions of pic_load_addr.
	(arm_finalize_pic): Generate either ARM or Thumb versions of
	pic_load_addr.

Index: gcc/config/arm/arm.md
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/arm/arm.md,v
retrieving revision 1.67
diff -p -r1.67 arm.md
*** arm.md	2000/11/27 16:29:52	1.67
--- arm.md	2000/11/28 23:36:49
***************
*** 4055,4074 ****
  ;; the insn alone, and to force the minipool generation pass to then move
  ;; the GOT symbol to memory.
  
! (define_insn "pic_load_addr"
    [(set (match_operand:SI 0 "s_register_operand" "=r")
  	(unspec:SI [(match_operand:SI 1 "" "mX")] 3))]
!   "TARGET_EITHER && flag_pic"
    "ldr%?\\t%0, %1"
    [(set_attr "type" "load")
!    (set (attr "pool_range")
! 	(if_then_else (eq_attr "is_thumb" "yes")
! 		      (const_int 1024)
! 		      (const_int 4096)))
!    (set (attr "neg_pool_range")
! 	(if_then_else (eq_attr "is_thumb" "yes")
! 		      (const_int 0)
! 		      (const_int 4084)))]
  )
  
  ;; This variant is used for AOF assembly, since it needs to mention the
--- 4055,4077 ----
  ;; the insn alone, and to force the minipool generation pass to then move
  ;; the GOT symbol to memory.
  
! (define_insn "pic_load_addr_arm"
    [(set (match_operand:SI 0 "s_register_operand" "=r")
  	(unspec:SI [(match_operand:SI 1 "" "mX")] 3))]
!   "TARGET_ARM && flag_pic"
    "ldr%?\\t%0, %1"
    [(set_attr "type" "load")
!    (set (attr "pool_range")     (const_int 4096))
!    (set (attr "neg_pool_range") (const_int 4084))]
! )
! 
! (define_insn "pic_load_addr_thumb"
!   [(set (match_operand:SI 0 "s_register_operand" "=l")
! 	(unspec:SI [(match_operand:SI 1 "" "mX")] 3))]
!   "TARGET_THUMB && flag_pic"
!   "ldr\\t%0, %1"
!   [(set_attr "type" "load")
!    (set (attr "pool_range") (const_int 1024))]
  )
  
  ;; This variant is used for AOF assembly, since it needs to mention the

Index: gcc/config/arm/arm.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/arm/arm.c,v
retrieving revision 1.117
diff -p -r1.117 arm.c
*** arm.c	2000/11/27 16:29:51	1.117
--- arm.c	2000/11/28 23:36:58
*************** legitimize_pic_address (orig, mode, reg)
*** 1920,1926 ****
        else
  	address = reg;
  
!       emit_insn (gen_pic_load_addr (address, orig));
  
        pic_ref = gen_rtx_MEM (Pmode,
  			     gen_rtx_PLUS (Pmode, pic_offset_table_rtx,
--- 1920,1929 ----
        else
  	address = reg;
  
!       if (TARGET_ARM)
! 	emit_insn (gen_pic_load_addr_arm (address, orig));
!       else
! 	emit_insn (gen_pic_load_addr_thumb (address, orig));
  
        pic_ref = gen_rtx_MEM (Pmode,
  			     gen_rtx_PLUS (Pmode, pic_offset_table_rtx,
*************** legitimize_pic_address (orig, mode, reg)
*** 1993,2000 ****
        if (NEED_GOT_RELOC)
  	{
  	  rtx pic_ref, address = gen_reg_rtx (Pmode);
  	  
- 	  emit_insn (gen_pic_load_addr (address, orig));
  	  pic_ref = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, address);
  	  
  	  emit_move_insn (address, pic_ref);
--- 1996,2007 ----
        if (NEED_GOT_RELOC)
  	{
  	  rtx pic_ref, address = gen_reg_rtx (Pmode);
+ 
+ 	  if (TARGET_ARM)
+ 	    emit_insn (gen_pic_load_addr_arm (address, orig));
+ 	  else
+ 	    emit_insn (gen_pic_load_addr_thumb (address, orig));
  	  
  	  pic_ref = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, address);
  	  
  	  emit_move_insn (address, pic_ref);
*************** arm_finalize_pic ()
*** 2044,2054 ****
  
    pic_rtx = gen_rtx_CONST (Pmode, gen_rtx_MINUS (Pmode, pic_tmp2, pic_tmp));
    
-   emit_insn (gen_pic_load_addr (pic_offset_table_rtx, pic_rtx));
    if (TARGET_ARM)
!     emit_insn (gen_pic_add_dot_plus_eight (pic_offset_table_rtx, l1));
    else
!     emit_insn (gen_pic_add_dot_plus_four (pic_offset_table_rtx, l1));
  
    seq = gen_sequence ();
    end_sequence ();
--- 2051,2066 ----
  
    pic_rtx = gen_rtx_CONST (Pmode, gen_rtx_MINUS (Pmode, pic_tmp2, pic_tmp));
    
    if (TARGET_ARM)
!     {
!       emit_insn (gen_pic_load_addr_arm (pic_offset_table_rtx, pic_rtx));
!       emit_insn (gen_pic_add_dot_plus_eight (pic_offset_table_rtx, l1));
!     }
    else
!     {
!       emit_insn (gen_pic_load_addr_thumb (pic_offset_table_rtx, pic_rtx));
!       emit_insn (gen_pic_add_dot_plus_four (pic_offset_table_rtx, l1));
!     }
  
    seq = gen_sequence ();
    end_sequence ();


More information about the Gcc-patches mailing list