This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
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