I'm now modifying the gcc's md file, for a mips(el) target. gcc src's version is 4.6.0.
I want to modify the sign-extend insn generation.
originally, mips use "lb
"/"lh
" instruction to sign-extend a byte/half.
but in my target CPU it doesn't has "lb
" and "lh
", it only support "lbu
" and "lhu
". so I have to generate such instructions to implement a sign-ext.
e.g.
lb %0,%1
become:
lbu %0,%1
srl %0,%0,24
sra %0,%0,24
similarly:
lh %0,%1
become:
lhu %0,%1
srl %0,%0,16
sra %0,%0,16
But, In original "md" file, two of these is a single pattern, it use macro to generate lb/lh instruction:
"l<SHORT:size>"
<SHORT:size> may be "b" or "h" --> "lb" or "lh"
but I want to get "24" from "b" ; get "16" form "h". How can I achieve this?
For the lb
case what you want is to define three rules using a define_insn
for lbu
, srl
and sra
respectively. Once that is done you define an expansion rule using a define_expand
for lb which expands into lbu
, srl
and sra
.
At expansion time GCC will transform lb into lbu
, srl
and sra
, meaning that during the RTL phase you won't have lb anymore but only things your backend will understand.
Similarly for lh
.
The internal documents are not the best in the world unless you're already in-the-know, however they can be useful to you to look particular details when reading other peoples backends.
On define_insn
: http://gcc.gnu.org/onlinedocs/gccint/Patterns.html#index-define_005finsn-3192
On define_expand
: http://gcc.gnu.org/onlinedocs/gccint/Expander-Definitions.html#index-define_005fexpand-3613
Enjoy.