[FFmpeg-devel] [PATCH] read_time() for SPARC
Michael Kostylev
michael.kostylev
Thu Sep 9 12:51:40 CEST 2010
On Thu Sep 9 11:31:15 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.
Nope.
> The presence of __sparc_v9__ clearly
>does not imply we are allowed to use 64-bit registers; __arch64__ does.
__sparc_v9__ means the v9 hardware, __arch64__ means the v9 abi.
>If the rd instruction requires a v9 CPU, the test should be for
>__sparc_v9__ && __arch64__.
The v9 abi is usable only on the appropriate hardware.
Michael
More information about the ffmpeg-devel
mailing list