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