On Dec 27, 2017, at 4:27 PM, BALATON Zoltan balaton@eik.bme.hu wrote:
On Wed, 27 Dec 2017, Programmingkid wrote:
On Dec 27, 2017, at 1:48 PM, Segher Boessenkool segher@kernel.crashing.org wrote:
On Wed, Dec 27, 2017 at 01:35:46PM -0500, John Arbuckle wrote:
+/* reads the lower timebase register ( -- tbl ) */ +static void get_tbl(void) +{
- int time;
- asm volatile("mftb %0" : "=r"(time)); // load from TBL register
- PUSH(time);
+}
This doesn't get TBL: on 64-bit implementations it gets all of TB. You'll have to mask out the high half if you want to get just TBL. Or, you could just use mftb (mfspr 268) on 64-bit systems, instead of the TBU dance that you need on 32-bit systems.
Segher
I wasn't aware that OpenBIOS supported 64-bit PowerPC. What if I change the type of the time variable to uint32_t. This type can only hold a 32-bit value, would the following code work on 64-bit PowerPC?
I don't know if it works (depends on the compiler implementation) but it looks safer to explicitely mask the unneded bits in a new line between the asm and PUSH.
/* reads the lower timebase register ( -- tbl ) */ static void get_tbl(void) { uint32_t time; asm volatile("mftb %0" : "=r"(time)); // load from TBL register PUSH(time); }
Also how would I test 64-bit PowerPC code in QEMU? If you could send the command-line needed that would help.
Look in openbios/include/arch/ppc/processor.h (and this is probably a better place for these kind of helpers than qemu/init.c as these are PPC specific not QEMU specific). However then you'd also need a way in Forth to detect 64bit. Elsewhere in ppc/qemu CONFIG_PPC64 also seems to be used and you may be able to test this in Forth, I've seen lines like:
[IFDEF] CONFIG_PPC64 " yes" [ELSE] " no" [THEN]
but not sure if this works. It seems to be cleaner to implement the tb@ function in C that returns the whole TB value instead of tbl@ and tbu@ and export that to Forth so you don't need to handle arch differences such as 64bit in Forth.
Regards, BALATON Zoltan
Ok I think this is what you want:
/* reads the lower timebase register ( -- tbl ) */ static void get_tbl(void) { uint32_t time; asm volatile("mftb %0" : "=r"(time)); // load from TBL register time = time & 0xffffffff; // Ensures the value is only 32-bit PUSH(time); }