[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