From ecc09f51d5c868604521d79f1b6b886d8087d353 Mon Sep 17 00:00:00 2001 From: rth Date: Sun, 19 Aug 2001 08:45:28 +0000 Subject: [PATCH] * config/i386/i386.md (tablejump): Make an expander; handle pic relative addressing here. (tablejump_1): Rename from tablejump_pic. (casesi): Remove. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@45028 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 7 ++++ 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 + * 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 + * regclass.c (fix_register): Fix typo. 2001-08-18 Richard Henderson 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 "" "")))] "" -- 2.7.4