diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index cedff732fa11c32c93fb790d196078f8f69bd18e..6d0befa4cd825d9f25234de2912a5d892884003d 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,14 @@
+2002-01-29  Richard Henderson  <rth@redhat.com>
+
+	* expr.c (force_operand): Ignore flag_pic for detecting pic
+	address loads.
+	* regclass.c (init_reg_sets_1): Test fixed_regs not flag_pic
+	for determining if PIC_OFFSET_TABLE_REGNUM is call-clobbered.
+	* resource.c (mark_target_live_regs): Use regs_invalidated_by_call
+	instead of open-coded loop.
+	* doc/tm.texi (PIC_OFFSET_TABLE_REGNUM): Clarify that it must
+	be fixed when in use.
+
 2002-01-29  Richard Henderson  <rth@redhat.com>
 
 	* sched-int.h (struct deps_reg): Add uses_length, clobbers_length.
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index a7a7c5b73f9d7d8a73b982cf525abba024a7891c..f3454f33c5c7db1ad71d950e741140eca10709b0 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -5603,7 +5603,8 @@ processor's ``application binary interface'' (ABI)@.  When this macro
 is defined, RTL is generated for this register once, as with the stack
 pointer and frame pointer registers.  If this macro is not defined, it
 is up to the machine-dependent files to allocate such a register (if
-necessary).
+necessary).  Note that this register must be fixed when in use (e.g.
+when @code{flag_pic} is true).
 
 @findex PIC_OFFSET_TABLE_REG_CALL_CLOBBERED
 @item PIC_OFFSET_TABLE_REG_CALL_CLOBBERED
diff --git a/gcc/expr.c b/gcc/expr.c
index 06914206ae7f7ef0c391afbdeb1cd945dc6f201c..2b8b0856b46f3742cafef1e3a8eeb29691aa6d81 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -5393,8 +5393,7 @@ force_operand (value, target)
   rtx subtarget = get_subtarget (target);
 
   /* Check for a PIC address load.  */
-  if (flag_pic
-      && (GET_CODE (value) == PLUS || GET_CODE (value) == MINUS)
+  if ((GET_CODE (value) == PLUS || GET_CODE (value) == MINUS)
       && XEXP (value, 0) == pic_offset_table_rtx
       && (GET_CODE (XEXP (value, 1)) == SYMBOL_REF
 	  || GET_CODE (XEXP (value, 1)) == LABEL_REF
diff --git a/gcc/regclass.c b/gcc/regclass.c
index 9bf07048db9562b217a5c1ac142d6b132fe0ca4b..d064e240b62691b7933d0b3b1ecc032293c09748 100644
--- a/gcc/regclass.c
+++ b/gcc/regclass.c
@@ -470,7 +470,7 @@ init_reg_sets_1 ()
 	;
 #endif
 #ifndef PIC_OFFSET_TABLE_REG_CALL_CLOBBERED
-      else if (i == PIC_OFFSET_TABLE_REGNUM && flag_pic)
+      else if (i == PIC_OFFSET_TABLE_REGNUM && fixed_regs[i])
 	;
 #endif
       else if (0
diff --git a/gcc/resource.c b/gcc/resource.c
index ebff8c61887486d9021035752543c4aec8f17a9a..5b19fe45450ccef6a7dc5bb0f44f438b68dcf184 100644
--- a/gcc/resource.c
+++ b/gcc/resource.c
@@ -1023,21 +1023,8 @@ mark_target_live_regs (insns, target, res)
 	      /* CALL clobbers all call-used regs that aren't fixed except
 		 sp, ap, and fp.  Do this before setting the result of the
 		 call live.  */
-	      for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
-		if (call_used_regs[i]
-		    && i != STACK_POINTER_REGNUM && i != FRAME_POINTER_REGNUM
-		    && i != ARG_POINTER_REGNUM
-#if HARD_FRAME_POINTER_REGNUM != FRAME_POINTER_REGNUM
-		    && i != HARD_FRAME_POINTER_REGNUM
-#endif
-#if ARG_POINTER_REGNUM != FRAME_POINTER_REGNUM
-		    && ! (i == ARG_POINTER_REGNUM && fixed_regs[i])
-#endif
-#if !defined (PIC_OFFSET_TABLE_REG_CALL_CLOBBERED)
-		    && ! (i == PIC_OFFSET_TABLE_REGNUM && flag_pic)
-#endif
-		    )
-		  CLEAR_HARD_REG_BIT (current_live_regs, i);
+	      AND_COMPL_HARD_REG_SET (current_live_regs,
+				      regs_invalidated_by_call);
 
 	      /* A CALL_INSN sets any global register live, since it may
 		 have been modified by the call.  */