This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
A happy problem caused by loongson2f's div.g instruction
- From: Zhang Le <r0bertz at gentoo dot org>
- To: gcc at gcc dot gnu dot org
- Cc: ruanbeihong at gmail dot com
- Date: Mon, 10 Nov 2008 02:09:04 +0800
- Subject: A happy problem caused by loongson2f's div.g instruction
Hi, all,
First of all, a little background on loongson2e/2f integer insn.
This new set of insns has 3 operands. Like:
div.g d,s,t
This is a real machine insn, not a macro.
And it delivers the result very fast.
This is the user guide if you are interested in more details:
http://www.gentoo-cn.org/~zhangle/Loongson2FUserGuide.pdf
I have recently tested this patch which added support for these insns:
http://gcc.gnu.org/ml/gcc-patches/2008-11/msg00273.html
For your convenience, you can get it here directly:
http://www.gentoo-cn.org/~zhangle/gcc-4.4.0-loongson-new_i_insn_and_prefetch.patch
And I found a problem. Take a look at the following c code:
int main() {
int a = 0;
int b = 8;
return a/b;
}
save it as div.c, compile it with:
gcc -march=loongson2f div.c -S
and the asm code produced is:
sw $0,12($fp)
li $2,8 # 0x8
sw $2,8($fp)
lw $3,12($fp)
lw $2,8($fp)
div.g $2,$3,$2
teq $2,$0,7
and the code will cause FPE. That means immediate after div.g, $2's value becomes 0.
I really can't find a second reasonably explanation.
So I think one of the possible solution would be to reverse the div.g and teq insn.
And I think this is not hard to do, just modify mips_output_division() function.
Also I think this is a better solution, since we can save a register.
The other would be make sure the destination register is different from source registers.
I have read some docs, but still not sure how to do it.
http://gcc.gnu.org/onlinedocs/gccint/Modifiers.html#Modifiers
If there is anything wrong, do tell me.
Also if you have any suggestions, I am all ears.
Thanks in advance!
Zhang, Le