public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
From: Zachary Turner <divisortheory@gmail.com>
To: gcc@gcc.gnu.org
Subject: naked functions on x86 architecture
Date: Fri, 12 Jun 2009 16:20:00 -0000	[thread overview]
Message-ID: <478231340906120920m74bd9c0i88861d5e759a8fb1@mail.gmail.com> (raw)

Hi,

I know this has been discussed before, I have read through some of the
archives and read about some of the rationale.  I want to raise it
again however, because I don't think anyone has ever presented a good
example of where it is really really useful on x86 architectures.

In general, it is very useful for selecting different versions of
instructions (byte, word, dword, qword) with a template
specialization.  I'll post some code that works under visual c++ 9.0
to demonstrate what I mean.  The following function finds the index of
the first zero (or nonzero with similar template specializations
replacing rep with repne) "element" of an arbitrarily sized array (and
is the fastest way I know to do so).

template<typename T> int __declspec(naked) scas();

template<> int __declspec(naked) scas<boost::uint8_t>() { __asm rep
scasb __asm mov eax, edi __asm ret }
template<> int __declspec(naked) scas<boost::uint16_t>() { __asm rep
scasw __asm mov eax, edi __asm ret }
template<> int __declspec(naked) scas<boost::uint32_t>() { __asm rep
scasd __asm mov eax, edi __asm ret }
#if (sizeof(void*) == sizeof(boost::uint64_t))
template<> int __declspec(naked) scas<boost::uint64_t>() { __asm rep
scasq __asm mov rax, rdi __asm ret }
#endif

template<typename T>
int find_first_nonzero_scas(T* x, int cnt)
{
    int result = 0;
    __asm {
        xor eax, eax
        mov edi, x
        mov ecx, cnt
    }
    result = scas<T>();
    result -= reinterpret_cast<int>(x);
    result /= sizeof(T);
    return --result;
}


This is one example, but it illustrates a general concept that I think
is really useful and I personally have used numerous times for lots of
other instructions than SCAS.  If there is a way to achieve this
without using a naked function then please advise.  I'd rather not
resort to an if/then/else when the value of every test is known at
compile time.

             reply	other threads:[~2009-06-12 16:20 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-06-12 16:20 Zachary Turner [this message]
2009-06-12 16:32 ` Paolo Bonzini
2009-06-12 17:25   ` Zachary Turner
2009-06-12 17:39     ` Andrew Haley
2009-06-12 17:56       ` Zachary Turner
2009-06-12 18:47         ` Andrew Haley

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=478231340906120920m74bd9c0i88861d5e759a8fb1@mail.gmail.com \
    --to=divisortheory@gmail.com \
    --cc=gcc@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).