Here's a concrete example of what I'm having problems with:
trying to use LowerOperation to replace one node with two nodes.
Imagine I have a new instruction "read_world" that sets the status flags
according to some kind of global state. In order to generate this instruction I
have a built-in function with the prototype "int __builtin_read_world(void)".
I also have a new instruction "read_flags" that sets a register according to the
status flags so I can translate a call to __builtin_read_world into a
"read_world" followed by a "read_flags" (at least as a last resort; I'm
expecting the "read_flags" instruction to be optimised away in most cases).
Attached is the patch I have attempted to use to implement this. It's mostly
boring (though I may have made a stupid error in the boring bits). The most
interesting bit is in ARMISelLowering.[ch] where I add the DAG nodes READ_WORLD
and READ_FLAGS and translate Intrinsic::arm_read_world into a READ_WORLD
followed by a READ_FLAGS. This is the bit I'm most worried about as I'm getting
ARMTargetLowering::LowerOperation to do something slightly more complicated than
usual. I may have broken some rule about what LowerOperation is allowed to do.
When I feed the patched Clang/LLVM with the source code
// clang -cc1 -triple thumbv7-eabi -target-cpu cortex-a8 t.c -O3 -S -o t.s
int f1()
{
return __builtin_read_world();
}
I get:
clang: InstrEmitter.cpp:667: ...
"#operands for dag node doesn't match .td file!"' failed.
What have I done wrong?
Any clues gratefully received.
Edmund
read_world.patch (5.71 KB)