Solução simples:
Uma abordagem comum é adicionar montagem embutida e codificar os bytes de instrução diretamente.
Por exemplo:
int main()
{
asm __volatile__ (".byte 0x90\n");
return 0;
}
compila (gcc -o3) em:
00000000004005a0 <main>:
4005a0: 90 nop
4005a1: 31 c0 xor %eax,%eax
4005a3: c3 retq
Portanto, basta substituir 0x90 pelos seus inst bytes. É claro que você não verá a instrução real em um objdump regular, e o programa provavelmente não funcionaria no seu sistema (a menos que você use uma das combinações NOP), mas o simulador deve reconhecê -lo se for implementado corretamente lá.
Observe que você não pode esperar que o compilador otimize bem para você quando não conhece esta instrução, e você deve cuidar e trabalhar com as opções de montagem em linha de montagem/entrada/saída se mudar de estado (registros, memória), para garantir a correção. Use otimizações apenas se precisar.
Solução complicada
A abordagem alternativa é implementar isso em seu compilador - isso pode ser feito no GCC, mas como declarado nos comentários LLVM é provavelmente um dos melhores para brincar, como foi projetado como uma plataforma de desenvolvimento do compilador, mas ainda é muito complicada Como o LLVM é mais adequado para os estágios de otimização de IR e é um pouco menos amigável ao tentar modificar os back-ends específicos do destino.
Ainda assim, é factível, e você deve fazer isso se também planeja fazer com que seu compilador decida quando emitir esta instrução. Porém, sugeriria começar da primeira opção, para ver se o seu simulador funciona com essa adição e só então gastando tempo no lado do compilador.
Se e quando você decidir implementar isso no LLVM, sua melhor aposta é defini -la como uma função intrínseca, há relativamente mais documentação sobre isso aqui - http://llvm.org/docs/extingllvm.html