Hello! My name is Andras Tantos and I just joined this list, so if I'm asking something off-topic or not following the rules of the community, please let me know.
What I'm working on is to port GCC (and Binutils) to a new CPU ISA, I call 'brew'. During developing for this target, I got the following error: >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> first.c: In function ‘test_call’: first.c:61:52: error: insn does not satisfy its constraints: 61 | int test_call(int a, int b) { return test_qm(a,b); } | ^ (insn 25 8 9 (set (reg:SI 6 $r6) (reg:SI 0 $pc)) "first.c":61:38 17 {*movsi} (nil)) during RTL pass: final first.c:61:52: internal compiler error: in final_scan_insn_1, at final.c:2811 0x6c4c23 _fatal_insn(char const*, rtx_def const*, char const*, int, char const*) ../../brew-gcc/gcc/rtl-error.c:108 0x6c4c4f _fatal_insn_not_found(rtx_def const*, char const*, int, char const*) ../../brew-gcc/gcc/rtl-error.c:118 0x643585 final_scan_insn_1 ../../brew-gcc/gcc/final.c:2811 0xb1ef3f final_scan_insn(rtx_insn*, _IO_FILE*, int, int, int*) ../../brew-gcc/gcc/final.c:2940 0xb1f207 final_1 ../../brew-gcc/gcc/final.c:1997 0xb1fbe6 rest_of_handle_final ../../brew-gcc/gcc/final.c:4285 0xb1fbe6 execute ../../brew-gcc/gcc/final.c:4363 Please submit a full bug report, with preprocessed source if appropriate. Please include the complete backtrace with any bug report. See <https://gcc.gnu.org/bugs/> for instructions. <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< Clearly, the compiler couldn't find a rule that works for this register move. The relevant section of the .md file is: >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> (define_expand "movsi" [(set (match_operand:SI 0 "general_operand" "") (match_operand:SI 1 "general_operand" ""))] "" " { /* If this is a store, force the value into a register. */ if (! (reload_in_progress || reload_completed)) { if (MEM_P (operands[0])) { operands[1] = force_reg (SImode, operands[1]); if (MEM_P (XEXP (operands[0], 0))) operands[0] = gen_rtx_MEM (SImode, force_reg (SImode, XEXP (operands[0], 0))); } else if (MEM_P (operands[1]) && MEM_P (XEXP (operands[1], 0))) operands[1] = gen_rtx_MEM (SImode, force_reg (SImode, XEXP (operands[1], 0))); } }") (define_insn "*movsi" [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,W,A,B,r,r,r") (match_operand:SI 1 "brew_general_mov_src_operand" "O,r,i,r,r,r,W,A,B"))] "register_operand (operands[0], SImode) || register_operand (operands[1], SImode)" "@ %0 <- %0 - %0 %0 <- %1 %0 <- %1 mem[%0] <- %1 mem[%0] <- %1 mem[%0] <- %1 %0 <- mem[%1] %0 <- mem[%1] %0 <- mem[%1]" ) <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< As you can imagine, I'm fairly new to GCC development, so I must be making some rookie mistake here, but I would have thought that the second alternative in the "*movsi" rule above would match the pattern. brew_general_mov_src_operand is defined as follows: >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> (define_predicate "brew_general_mov_src_operand" (match_code "mem,const_int,reg,subreg,symbol_ref,label_ref,const") { /* Any (MEM LABEL_REF) is OK. That is a pc-relative load. */ if (MEM_P (op) && GET_CODE (XEXP (op, 0)) == LABEL_REF) return 1; if (MEM_P (op) && GET_CODE (XEXP (op, 0)) == PLUS && GET_CODE (XEXP (XEXP (op, 0), 0)) == REG && GET_CODE (XEXP (XEXP (op, 0), 1)) == CONST_INT ) return 1; /* Any register is good too */ if (REG_P(op)) return 1; /* PC as source is also acceptable */ if (op == pc_rtx) return 1; return general_operand (op, mode); }) <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< Thanks for all the help, Andras