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:
parent
ec523c2f34
commit
9067592172
@ -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.
|
||||
|
@ -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 "" "")))]
|
||||
""
|
||||
|
Loading…
Reference in New Issue
Block a user