https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118816
Bug ID: 118816 Summary: Accessing MIPS coprocessor 2/3 register variables generates invalid assembly Product: gcc Version: 14.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: johannes_schiller at web dot de Target Milestone: --- When using a global register variable to access registers on MIPS coprocessors 2 or 3, GCC will generate assembly when accessing those, that is incompatible with the assembler. It works perfectly for coprocessor 0, and coprocessor 1 can't be accessed this way since it's the FPU. Sample Code (also available via Godbolt: https://godbolt.org/z/e1vjsK7aE): register unsigned int cop0_r0 asm("c0r0"); register unsigned int cop2_r0 asm("c2r0"); register unsigned int cop3_r0 asm("c3r0"); void test() { cop0_r0 = 10; cop2_r0 = 10; cop3_r0 = 10; } GCC Output: /tmp/cce5eUyF.s: Assembler messages: /tmp/cce5eUyF.s:34: Error: invalid operands `mtc2 $2,$c2r0' /tmp/cce5eUyF.s:37: Error: invalid operands `mtc3 $2,$c3r0' Compiler returned: 1 Assembly Output: test: daddiu $sp,$sp,-16 sd $fp,8($sp) move $fp,$sp li $2,10 # 0xa mtc0 $2,$0 mtc2 $2,$c2r0 mtc3 $2,$c3r0 nop move $sp,$fp ld $fp,8($sp) daddiu $sp,$sp,16 jr $31 nop So the problem seems to be, that GCC doesn't translate the register names for COP2/3. Looking at the code (gcc/config/mips/mipc.cc) it seems like the translation from "cNr0" to "$0" is only done for COP0. Patching the code locally to also perform the same for COP2/3 did resolve the issue for me. I'll attach a patch, but unfortunately I don't have the capacity to go through the proper steps to submit it.