Embedded systems are usually very limited in resources, so another computer is used to compile their own programs.
Compilers usually have all higher-level languages (like C) converted to a low-level (but still portable) Intermediate Representation, further compiled down to the assembly language of choice.
Alas, for GCC, that intermediate representation is internal, eventually exported as GIMPLE for debugging, but hardly ever re-imported back for compiling. The same program is in charge of parsing C's syntax then immediately generating the assembly.
To have different target assembly, GCC offers different binaries: one for each target architecture, such as avr-gcc for AVR, arm-none-eabi-gcc for ARM, mips-gcc for MIPS, riscv64-gcc for RISC-V 64-bit...
Each of these binaries is preconfigured to use the collection of tools with that same prefix, and the right C libraries.
There is nothing that require a binary to be produced on a CPU of the same architecture, and cross compilers are normal compilers. It is only for convenience that the GCC compiler running on an amd64 machine is named "gcc" instead of "amd64-gcc".
In the end, a "native" compiler is just a cross-compiler that happen to compile for the same architecture as the one running it: a amd64-gcc compiler is built with the same source and does the same thing regardless wheter it runs on an amd64, i386, or arm computer.