Hi, I am working on gcc 4.1.1 and Itanium architecture. I want to modify the machine description of ia64.md to add some checks before each ld instruction. the following is the original define_insn:
(define_insn "*movqi_internal" [(set (match_operand:QI 0 "destination_operand" "=r,r,r, m, r,*f,*f") (match_operand:QI 1 "move_operand" "rO,J,m,rO,*f,rO,*f"))] "ia64_move_ok (operands[0], operands[1])" "@ mov %0 = %r1 addl %0 = %1, r0 ld1%O1 %0 = %1%P1 st1%Q0 %0 = %r1%P0 getf.sig %0 = %1 setf.sig %0 = %r1 mov %0 = %1" [(set_attr "itanium_class" "ialu,ialu,ld,st,frfr,tofr,fmisc")]) I observe that there is a ld instruction in 3rd alternative, so I add a new define_insn before it in the hope that it will be matched firstly. (define_insn "*ld_movqi_internal" [(set (match_operand:QI 0 "destination_operand" "=r") (match_operand:QI 1 "move_operand" "m"))] "ia64_move_ok (operands[0], operands[1]) && flag_check_ld" { printf("define_insn ld_movqi_internal\n"); return "ld1%O1 %0 = %1%P1"; } [(set_attr "itanium_class" "ld")] I keep every thing the same as 3rd alternative in original define_insn except using C statement to return the desired output template. However, when I use the newly builded gcc to compile the following program, it crashes. #include <stdio.h> char characters[8192]={'a',}; int main() { char c = characters[0]; printf("Hello World! c:%c\n", c); } the error reported is: hi.c:9: error: unable to generate reloads for: (insn 10 9 12 1 (set (mem/c/i:QI (reg/f:DI 111 loc79) [0 c+0 S1 A128]) (reg:QI 14 r14 [orig:342 characters ] [342])) 3 {*gift_movqi_internal_ld} (nil) (expr_list:REG_DEAD (reg:QI 14 r14 [orig:342 characters ] [342]) (nil))) hi.c:9: internal compiler error: in find_reloads, at reload.c:3738 In IA64, the first pesudo register number is 334, thus register 111 and register 14 are both hardware registers. I looked at find_reloads at reload.c and find the following code fragement and comment: /* The operands don't meet the constraints. goal_alternative describes the alternative that we could reach by reloading the fewest operands. Reload so as to fit it. */ if (best == MAX_RECOG_OPERANDS * 2 + 600) { /* No alternative works with reloads?? */ if (insn_code_number >= 0) fatal_insn ("unable to generate reloads for:", insn); ... So, what is going on here? Especially, what is find_reloads going to finish and why it is going wrong here... I would appreciate any help on this question, thx! Best Regards --andy.wu