i386.md (tablejump): Make an expander; handle pic relative addressing here.

* config/i386/i386.md (tablejump): Make an expander; handle
        pic relative addressing here.
        (tablejump_1): Rename from tablejump_pic.
        (casesi): Remove.

From-SVN: r45028
This commit is contained in:
Richard Henderson 2001-08-19 01:45:28 -07:00 committed by Richard Henderson
parent ec523c2f34
commit 9067592172
2 changed files with 21 additions and 71 deletions

View 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.

View File

@ -12954,80 +12954,23 @@
[(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 "" "")))]
""