[FFmpeg-devel] [PATCH] read_time() for SPARC
Måns Rullgård
mans
Thu Sep 9 12:31:15 CEST 2010
Michael Kostylev <michael.kostylev at gmail.com> writes:
> On Wed Sep 8 21:54:43 2010
> M?ns Rullg?rd wrote:
>
>>>>>>> The attached patch provides access to a 63-bit tick counter which is
>>>>>>> available on the v9 cpus in the manner compatible with the v8+ abi.
>>>>>>>
>>>>>>> +#ifndef AVUTIL_SPARC_TIMER_H
>>>>>>> +#define AVUTIL_SPARC_TIMER_H
>>>>>>> +
>>>>>>> +#ifdef __sparc_v9__
>>>>>>> +
>>>>>>> +#include <stdint.h>
>>>>>>> +
>>>>>>> +#define AV_READ_TIME read_time
>>>>>>> +
>>>>>>> +static inline uint64_t read_time(void)
>>>>>>> +{
>>>>>>> + uint64_t tc;
>>>>>>> + __asm__ volatile("rd %%tick,%%g1\n\t"
>>>>>>> + "stx %%g1,%0\n\t"
>>>>>>> + : "=m" (tc) :: "g1");
>>>>>>> + return tc;
>>>>>>> +}
>>>>>>
>>>>>>Why can't you read the counter directly to whatever register 'tc'
>>>>>>lives in?
>>>>>
>>>>> That will not work with v8+, tc will be filled with the least significant
>>>>> 32 bits.
>>>>
>>>>Why?
>>>
>>> The rd instruction uses only register operands and the r constraint
>>> is considered 32-bit (the rest bits are filled by the compiler). I
>>> see no register constraint which would be 64-bit with v9 and v8+.
>>
>>$ cat sparc.c
>>long long foo()
>>{
>> long long tc;
>> __asm__ ("rd %%tick, %0" : "=r"(tc));
>> return tc;
>>}
>>$ sparc64-unknown-linux-gnu-gcc -O3 -c sparc.c && sparc64-unknown-linux-gnu-objdump -d sparc.o
>>sparc.o: file format elf64-sparc
>>
>>Disassembly of section .text:
>>
>>0000000000000000 <foo>:
>> 0: 91 41 00 00 rd %tick, %o0
>> 4: 81 c3 e0 08 retl
>> 8: 01 00 00 00 nop
>>$ sparc64-unknown-linux-gnu-gcc -mv8plus -O3 -c sparc.c && sparc64-unknown-linux-gnu-objdump -d sparc.o
>>sparc.o: file format elf64-sparc
>
> That's wrong. You must use -m32. How it looks on a real machine:
-m32 usually implies a pure 32-bit build. 64-bit registers will of
course not be used with such settings. The whole v8+ thing is
thoroughly confusing too.
> % gcc -O3 -c sparc.c
> /tmp/ccdAPwzx.s: Assembler messages:
> /tmp/ccdAPwzx.s:9: Error: Architecture mismatch on "rd".
> /tmp/ccdAPwzx.s:9: (Requires v9|v9a|v9b; requested architecture is sparclite.)
>
> % gcc -mcpu=v9 -O3 -c sparc.c && objdump -d sparc.o
>>sparc.o: file format elf32-sparc
>
> Disassembly of section .text:
>
> 00000000 <foo>:
> 0: 85 41 00 00 rd %tick, %g2
> 4: 92 10 00 03 mov %g3, %o1
> 8: 81 c3 e0 08 retl
> c: 90 10 00 02 mov %g2, %o0
That is exactly what I'd expect from a 32-bit build that happens to be
running on a 64-bit machine.
> Not better when inlined.
>
> % file sparc.o
> sparc.o: ELF 32-bit MSB relocatable, SPARC32PLUS, V8+ Required, version 1 (SYSV), not stripped
>
> Speaking of macros:
>
> % gcc -E -xc -dM /dev/null | grep 'arch\|sparc'
> #define sparc 1
> #define __sparc__ 1
> #define __sparc 1
> #define __sparc_v8__ 1
>
> % gcc -mcpu=v9 -E -xc -dM /dev/null | grep 'arch\|sparc'
> #define sparc 1
> #define __sparc__ 1
> #define __sparc 1
> #define __sparc_v9__ 1
This is a 32-bit build optimised for v9 CPU. Makes sense.
> % gcc -m64 -E -xc -dM /dev/null | grep 'arch\|sparc'
> #define sparc 1
> #define __sparc__ 1
> #define __sparc 1
> #define __arch64__ 1
Unspecified 64-bit CPU.
> % gcc -m64 -mcpu=ultrasparc -E -xc -dM /dev/null | grep 'arch\|sparc'
> #define sparc 1
> #define __sparc__ 1
> #define __sparc 1
> #define __sparc_v9__ 1
> #define __arch64__ 1
>
> -> #if defined (__sparc_v9__) || defined (__arch64__)
You are contradicting yourself. The presence of __sparc_v9__ clearly
does not imply we are allowed to use 64-bit registers; __arch64__ does.
If the rd instruction requires a v9 CPU, the test should be for
__sparc_v9__ && __arch64__.
--
M?ns Rullg?rd
mans at mansr.com
More information about the ffmpeg-devel
mailing list