This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

writing casesi (was: Re: arm/thumb bugs)


Heyho!

[ARM/Thumb produces non-working code for switch statements when used
with -fpic]

Nick Clifton wrote:

> Have a look in the arm.md file.  Find "casesi" and "casesi_internal".
> These are the patterns used for switch table generation for the ARM.
> You will porobably want to define similar patterns for the THUMB.

Ok, I'm trying - but not getting anywhere right now.

I'm calling the thumbpic_casesi from casesi if TARGET_THUMB && flag_pic.
This failes when compiling a switch statement, saying there'd be an
unrecognizable pattern.

The define_expand:
(define_expand "thumbpic_casesi"
  [(set (match_dup 5)
        (minus:SI (match_operand:SI 0 "" "")
                  (match_operand:SI 1 "" "")))
   (set (pc)
        (if_then_else (gtu (match_dup 5)
                           (match_operand 2 "" ""))
                      (label_ref (match_operand 4 "" ""))
                      (pc)))
   (set (match_dup 6)
        (mult:SI (match_dup 5)
                 (const_int 2)))
   (set (match_dup 7)
        (label_ref (match_operand 3 "" "")))
   (set (match_dup 8)
        (plus:SI (match_dup 6)
                 (match_dup 7)))
    (set (pc)
         (match_dup 8))]
  "TARGET_THUMB && flag_pic"
  "{
    operands[5] = gen_reg_rtx (SImode);
    operands[6] = gen_reg_rtx (SImode);
    operands[7] = gen_reg_rtx (SImode);
    operands[8] = gen_reg_rtx (SImode);
  }"
)


This results in:
]$ arm-uclinux-gcc -O3 -mno-sched-prolog -dr -save-temps         -mthumb
-fpic -c -o 01.o.thumbpic 01.c -da -dP
01.c: In function `bla':
01.c:20: Unrecognizable insn:

(insn 151 150 152 (set (reg/f:SI 54)
        (label_ref 154)) -1 (nil)
    (expr_list:REG_EQUAL (label_ref 154)
        (insn_list:REG_LABEL 154 (nil))))
01.c:20: Internal compiler error in extract_insn, at recog.c:2218
Please submit a full bug report,
with preprocessed source if appropriate.
See <URL:http://www.gnu.org/software/gcc/bugs.html> for instructions.

I tried to define a pattern to catch this, but without success so far:
(define_insn "*thumbpic_movaddr"
  [(set (match_operand:SI 0 "s_register_operand" "=l")
        (match_operand:DI 1 "address_operand" "p"))]
  "TARGET_THUMB && flag_pic"
  "adr\\t%0, %a1"
  [(set_attr "length" "2")]
)
 seems not to do what I want.

The other possibility would be not to define casesi, but to have the
addr_diff_vec generate not the series of branch instructions that is
generated now, but the series of offsets as Philip Blundell suggested.
Only I couldn't find out where I would specify this (defining
CASE_VECTOR_PC_RELATIVE in arm.h did not change anything.)

 
greets from Zürich
-- vbi


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]