Hi gcc gurus,
I'm trying to port GCC to a new architecture, I'm new to gcc, and have
little problems defining add correctly.
My target has 2 types of (DI mode) registers, so I defined 2 classes:
- class D (data) regs can be used for computations, and that includes
operations such as additions and increments:
reg += small immediate
or reg1 += reg2
- class A (address) can be used as base for loads, also they can be
modified with moves (between A-regs and from/to D-regs, not from
immediates) and with increments:
reg += large immediate
So first for adddi3 I have defined the following:
(define_constraint "I"
"Signed 6-bit integer constant for binops."
(and (match_code "const_int")
(match_test "IN_RANGE (ival, -24, 32)")))
(define_register_constraint "A" "ADDR_REGS"
"The address registers.")
(define_register_constraint "D" "DATA_REGS"
"The general (data) registers.")
(define_predicate "reg_or_18bit_signed_operand"
(if_then_else (match_code "const_int")
(match_test "IN_RANGE (INTVAL (op), -(1 << 17), (1 << 17) - 1)")
(match_operand 0 "register_operand")))
(define_insn "adddi3"
[(set (match_operand:DI 0 "register_operand" "=D,D,A")
(plus:DI
(match_operand:DI 1 "register_operand" "%0,0,0")
(match_operand:DI 2 "reg_or_18bit_signed_operand" "I,D,n")))]
""
"@
addi %0, %2
add %0, %2
adda %0, %2")
But this doesn't work, I get:
error: insn does not satisfy its constraints:
(insn 1424 1423 141 (set (reg:DI 2 r2)
(plus:DI (reg:DI 2 r2)
(const_int 40 [0x28])))
/home/jmsaffroy/cygnus/src/newlib/libc/time/strptime.c:165 24 {adddi3}
(expr_list:REG_EQUIV (plus:DI (reg/f:DI 70 a6)
(const_int 40 [0x28]))
(nil)))
(r2 is a D-reg, a6 is an A-reg.)
It seems I was expecting too much intelligence from reload, or I didn't
give enough hints.
So I tried separating the add instructions for A-regs and D-regs into
different patterns with more restrictive predicates for each pattern (so
add for A regs can have large increments), but then I get other ICEs
which I don't understand (first assert in elimination_costs_in_insn fails).
Does anyone have a hint how I should approach this? Is a define_expand
required, or something else?
Cheers,
Jean-Marc