i386.md (tablejump): Make an expander; handle pic relative addressing here.
authorRichard Henderson <rth@redhat.com>
Sun, 19 Aug 2001 08:45:28 +0000 (01:45 -0700)
committerRichard Henderson <rth@gcc.gnu.org>
Sun, 19 Aug 2001 08:45:28 +0000 (01:45 -0700)
        * config/i386/i386.md (tablejump): Make an expander; handle
        pic relative addressing here.
        (tablejump_1): Rename from tablejump_pic.
        (casesi): Remove.

From-SVN: r45028

gcc/ChangeLog
gcc/config/i386/i386.md

index 1190c4e16dd144a7ff0d4e22bdf6103a6f885e94..abc349fdc3a27084386a48c49a0a19f14f30f2e9 100644 (file)
@@ -1,3 +1,10 @@
+2001-08-19  Richard Henderson  <rth@redhat.com>
+
+       * config/i386/i386.md (tablejump): Make an expander; handle
+       pic relative addressing here.
+       (tablejump_1): Rename from tablejump_pic.
+       (casesi): Remove.
+
 2001-08-19  Richard Henderson  <rth@redhat.com>
 
        * regclass.c (fix_register): Fix typo.
index 75fb5027b28ba1b01e5fc13108f83733e3458631..13c7d00f5c0e2c91f7f4758a540982a604af4925 100644 (file)
   [(set_attr "type" "ibr")
    (set_attr "length_immediate" "0")])
 
-(define_insn "tablejump"
-  [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
-   (use (label_ref (match_operand 1 "" "")))]
-  "! flag_pic"
-  "jmp\t%A0"
-  [(set_attr "type" "ibr")
-   (set_attr "length_immediate" "0")])
-
-;; Implement switch statements when generating PIC code.  Switches are
-;; implemented by `tablejump' when not using -fpic.
-;;
-;; Emit code here to do the range checking and make the index zero based.
-;;
-;; Each entry in the "addr_diff_vec" looks like this as the result of the
-;; two rules below:
-;; 
-;;     .long _GLOBAL_OFFSET_TABLE_+[.-.L2]
-;; 
-;; 1. An expression involving an external reference may only use the
-;;    addition operator, and only with an assembly-time constant.
-;;    The example above satisfies this because ".-.L2" is a constant.
-;; 
-;; 2. The symbol _GLOBAL_OFFSET_TABLE_ is magic, and at link time is
-;;    given the value of "GOT - .", where GOT is the actual address of
-;;    the Global Offset Table.  Therefore, the .long above actually
-;;    stores the value "( GOT - . ) + [ . - .L2 ]", or "GOT - .L2".  The
-;;    expression "GOT - .L2" by itself would generate an error from as(1).
-;; 
-;; The pattern below emits code that looks like this:
-;; 
-;;     movl %ebx,reg
-;;     subl TABLE@GOTOFF(%ebx,index,4),reg
-;;     jmp reg
-;; 
-;; The addr_diff_vec contents may be directly referenced with @GOTOFF, since
-;; the addr_diff_vec is known to be part of this module.
-;; 
-;; The subl above calculates "GOT - (( GOT - . ) + [ . - .L2 ])", which
-;; evaluates to just ".L2".
-
-(define_expand "casesi"
-  [(set (match_dup 5)
-       (match_operand:SI 0 "general_operand" ""))
-   (parallel [(set (match_dup 6)
-                  (minus:SI (match_dup 5)
-                            (match_operand:SI 1 "general_operand" "")))
-             (clobber (reg:CC 17))])
-   (set (reg:CC 17)
-       (compare:CC (match_dup 6)
-                   (match_operand:SI 2 "general_operand" "")))
-   (set (pc)
-       (if_then_else (gtu (reg:CC 17)
-                          (const_int 0))
-                     (label_ref (match_operand 4 "" ""))
-                     (pc)))
-   (parallel
-     [(set (match_dup 7)
-          (minus:SI (match_dup 8)
-            (mem:SI (plus:SI (plus:SI (mult:SI (match_dup 6) (const_int 4))
-                             (match_dup 8))
-                    (const (unspec [(label_ref (match_operand 3 "" ""))] 7))))))
-      (clobber (reg:CC 17))])
-   (parallel [(set (pc) (match_dup 7))
-             (use (label_ref (match_dup 3)))])]
-  "flag_pic"
+(define_expand "tablejump"
+  [(parallel [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
+             (use (label_ref (match_operand 1 "" "")))])]
+  ""
 {
-  operands[5] = gen_reg_rtx (SImode);
-  operands[6] = gen_reg_rtx (SImode);
-  operands[7] = gen_reg_rtx (SImode);
-  operands[8] = pic_offset_table_rtx;
-  current_function_uses_pic_offset_table = 1;
+  /* In PIC mode, the table entries are stored GOT-relative.  Convert
+     the relative address to an absolute address.  */
+  if (flag_pic)
+    {
+      operands[0] = expand_simple_binop (Pmode, MINUS, pic_offset_table_rtx,
+                                        operands[0], NULL_RTX, 1,
+                                        OPTAB_DIRECT);
+      current_function_uses_pic_offset_table = 1;
+    }
 })
 
-(define_insn "*tablejump_pic"
+(define_insn "*tablejump_1"
   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
    (use (label_ref (match_operand 1 "" "")))]
   ""