Segher Boessenkool <seg...@kernel.crashing.org> writes:
Hi Tulio,
Hi Segher,
+(define_expand "rs6000_get_timebase"
+ [(use (match_operand:DI 0 "gpc_reg_operand" ""))]
+ ""
+ "
+{
+ if (TARGET_POWERPC64)
+ emit_insn (gen_rs6000_get_timebase_ppc64 (operands[0]));
+ else
+ emit_insn (gen_rs6000_get_timebase_ppc32 (operands[0]));
+ DONE;
+}")
Please don't put quotes around the C block.
Fixed.
+(define_insn "rs6000_get_timebase_ppc32"
+ [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
+ (unspec_volatile:DI [(const_int 0)] UNSPECV_GETTB))
+ (clobber (match_scratch:SI 1 "=r"))
+ (clobber (match_scratch:CC 2 "=x"))]
You can do "y" instead, to allow all CRn fields.
Fixed.
+ "!TARGET_POWERPC64"
+{
+ if (WORDS_BIG_ENDIAN)
+ if (TARGET_MFCRF)
+ {
+ return "mfspr %0, 269\;"
+ "mfspr %L0, 268\;"
+ "mfspr %1, 269\;"
+ "cmpw %0,%1\;"
+ "bne- $-16";
+ }
+ else
+ {
+ return "mftbu %0\;"
+ "mftb %L0\;"
+ "mftbu %1\;"
+ "cmpw %0,%1\;"
+ "bne- $-16";
+ }
+ else
+ if (TARGET_MFCRF)
+ {
+ return "mfspr %L0, 269\;"
+ "mfspr %0, 268\;"
+ "mfspr %1, 269\;"
+ "cmpw %L0,%1\;"
+ "bne- $-16";
+ }
+ else
+ {
+ return "mftbu %L0\;"
+ "mftb %0\;"
+ "mftbu %1\;"
+ "cmpw %L0,%1\;"
+ "bne- $-16";
+ }
+})
I don't think TARGET_MFCRF is correct. For example, if you use
-mcpu=powerpc64 (which doesn't set this flag) you will get code
that does not run on the newer machines.
Sorry, but it seems to be working here...
I explain how I tested this in the end of the email.
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index e850266..b3fc236 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -13660,6 +13660,8 @@ float __builtin_rsqrtf (float);
double __builtin_recipdiv (double, double);
double __builtin_rsqrt (double);
long __builtin_bpermd (long, long);
+uint64_t __builtin_ppc_get_timebase ();
+unsigned long __builtin_ppc_mftb ();
@end smallexample
This is section "PowerPC AltiVec/VSX Built-in Functions"; there
should be a preceding separate "PowerPC Built-in Functions"
section.
Some of the current documentation should go there, too.
Agreed.
I'm changing this.
@@ -13671,6 +13673,14 @@ The @code{__builtin_recipdiv}, and
@code{__builtin_recipdivf}
functions generate multiple instructions to implement division
using
the reciprocal estimate instructions.
+The @code{__builtin_ppc_get_timebase} and
@code{__builtin_ppc_mftb}
+functions generate instructions to read the Time Base
Register. The
+@code{__builtin_ppc_get_timebase} function may generate
multiple
+instructions and always return the 64 bits of the Time Base
Register. The
s/return/returns/
Fixed.
+@code{__builtin_ppc_mftb} function always generate one
instruction and
generates
Fixed.
+returns the Time Base Register value as an unsigned long,
throwing away
+the most significant word on 32-bit environments.
Looks good other than those nits, and the MFCRF thing. Oh, and
you
didn't say how you tested it (what targets).
Sorry, I run the test suite on a Power7 running a 64-bit
environment.
Then, I manually built and run a modified copy of the 2 included
tests that
that only print the TBR values a 3 times to make sure they were
increasing.
I did this for both 32 and 64 bits on a Power3 and a Power7,
making sure to use
the correct -mcpu.
In the end I checked that the generated assembly was right for
Power3, Power7
and some random chooses I've done.
Here are some snippets of code for __builtin_ppc_get_timebase,
i.e.:
- -m64 -mcpu=power7
.L.main:
std 31,-8(1)
stdu 1,-80(1)
mr 31,1
mfspr 9, 268
std 9,56(31)
li 9,0
stw 9,48(31)
b .L2
- -m32 -mcpu=power3
main:
stwu 1,-48(1)
stw 31,44(1)
mr 31,1
mftbu 8
mftb 9
mftbu 10
cmpw 8,10
bne- $-16
stw 8,24(31)
stw 9,28(31)
lfd 0,24(31)
stfd 0,16(31)
li 9,0
stw 9,8(31)
b .L2
- -m64 -mcpu=power3
.L.main:
std 31,-8(1)
stdu 1,-80(1)
mr 31,1
mftb 9
std 9,56(31)
li 9,0
stw 9,48(31)
b .L2
Thanks,
--
Tulio Magno