From: Richard Henderson Date: Sun, 19 Aug 2001 08:45:28 +0000 (-0700) Subject: i386.md (tablejump): Make an expander; handle pic relative addressing here. X-Git-Tag: prereleases/libstdc++-3.0.95~2555 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=90675921729800c0eedd2b7ae1db8d3fd1826c55;p=thirdparty%2Fgcc.git 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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 1190c4e16dd1..abc349fdc3a2 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +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. diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 75fb5027b28b..13c7d00f5c0e 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 "" "")))] ""