diff options
author | Richard Henderson <rth@redhat.com> | 2001-08-19 01:45:28 -0700 |
---|---|---|
committer | Richard Henderson <rth@gcc.gnu.org> | 2001-08-19 01:45:28 -0700 |
commit | 90675921729800c0eedd2b7ae1db8d3fd1826c55 (patch) | |
tree | ffb8f190dd035b1e27f2e487319c805f4deca9e7 | |
parent | ec523c2f3426dc196922312299b28f3d839ddb5d (diff) | |
download | gcc-90675921729800c0eedd2b7ae1db8d3fd1826c55.zip gcc-90675921729800c0eedd2b7ae1db8d3fd1826c55.tar.gz gcc-90675921729800c0eedd2b7ae1db8d3fd1826c55.tar.bz2 |
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
-rw-r--r-- | gcc/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/config/i386/i386.md | 85 |
2 files changed, 21 insertions, 71 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 1190c4e..abc349f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,12 @@ 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. 2001-08-18 Richard Henderson <rth@redhat.com> diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 75fb502..13c7d00 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -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 "" "")))] "" |