Solución simple:
Un enfoque común es agregar ensamblaje en línea y codificar los bytes de instrucción directamente.
Por ejemplo:
int main()
{
asm __volatile__ (".byte 0x90\n");
return 0;
}
Compila (GCC -O3) en:
00000000004005a0 <main>:
4005a0: 90 nop
4005a1: 31 c0 xor %eax,%eax
4005a3: c3 retq
Así que simplemente reemplace 0x90 con sus bytes instancia. Por supuesto, no verá la instrucción real en un objdump regular, y el programa probablemente no se ejecutaría en su sistema (a menos que use una de las combinaciones NOP), pero el simulador debe reconocerlo si se implementa correctamente allí.
Tenga en cuenta que no puede esperar que el compilador le optimice bien cuando no conozca esta instrucción, y debe tener cuidado y trabajar con opciones de clobber/entrada/salida de ensamblaje en línea si cambia de estado (registros, memoria), a Asegurar la corrección. Use optimizaciones solo si es necesario.
Solución complicada
El enfoque alternativo es implementar esto en su compilador: se puede hacer en GCC, pero como se indica en los comentarios, LLVM es probablemente uno de los mejores para jugar, ya que está diseñado como una plataforma de desarrollo del compilador, pero aún es muy complicado Como LLVM es más adecuado para las etapas de optimización IR, y es algo menos amigable cuando se trata de modificar los backends específicos del objetivo.
Aún así, es factible, y debe hacerlo si también planea que su compilador decida cuándo emitir esta instrucción. Sin embargo, sugeriría comenzar desde la primera opción, para ver si su simulador incluso funciona con esta adición, y solo entonces pasar tiempo en el lado del compilador.
Si decide implementar esto en LLVM, su mejor opción es definirlo como una función intrínseca, hay relativamente más documentación sobre esto aquí, http://llvm.org/docs/extendingllvm.html