Raw instruction code on sparc64?

1 view
Skip to first unread message

Mark Glines

unread,
Feb 3, 2009, 11:25:03 AM2/3/09
to parro...@lists.parrot.org
Hi,

There's some code at the top of trace_system_areas() in src/gc/system.c
to flush the register windows on sparc. The code in question:

/* Flush the register windows. For sparc systems, we use hand-coded
assembly language to create a small function that flushes the
register windows. Store the code in a union with a double to
ensure proper memory alignment. */
static union {
unsigned int insns[4];
double align_hack[2];
} u = { {
# ifdef __sparcv9
0x81580000, /* flushw */
# else
0x91d02003, /* ta ST_FLUSH_WINDOWS */
# endif
0x81c3e008, /* retl */
0x01000000 /* nop */
} };

/* Turn the array of machine code values above into a function
pointer.
Call the new function pointer to flush the register windows. */
static void (*fn_ptr)(void) = (void (*)(void))&u.align_hack[0];
fn_ptr();


According to "svn blame", some of this code dates all the way back to
2002, so I'm not really sure who to ask. We have reports of failed
builds on sparc64/openbsd (see Trac #271) which raised the question:
will this code work on sparc64?
_______________________________________________
http://lists.parrot.org/mailman/listinfo/parrot-dev

Andrew Whitworth

unread,
Feb 3, 2009, 11:50:04 AM2/3/09
to parro...@lists.parrot.org
oops, clicked reply" instead of "reply all".

--Andrew Whitworth


---------- Forwarded message ----------
From: Andrew Whitworth <wknig...@gmail.com>
Date: Tue, Feb 3, 2009 at 11:48 AM
Subject: Re: Raw instruction code on sparc64?
To: Mark Glines <ma...@glines.org>

For the record, this code used to be located in src/cpu_dep.c, but I
moved it to src/gc/system.c earlier this week as part of the GC
cleanups. The purpose of this function is to extract pointer values
from the general-purpose registers of the host processor, and have
them be stored somewhere on the stack. With this done, we then scan
through the entire stack looking for pointers to mark as "alive" in
the GC.

A few points:
1) I don't know why Sparc9 and IA64 are treated specially here, don't
they have PARROT_SET_JMP on those platforms? Or if it does, doesn't
setjmp do what it should be doing there?
2) I don't like the idea of hand-coded assembly here in the C. It
certainly is a clever solution, but terribly unreadable and
non-portable. Better would be to include a separate assembly file and
have it be assembled at build time on systems that need it. We already
do this for IA64 in the file config/gen/platform/ia64/asm.s, I think
we should be able to do this for Sparc9 as well. Do we have anybody
knowledgable in Sparc9 assembly?
3) I can't speak for whether or not this code does what it claims to
do or whether it's portable to 64-bit systems. I suspect that it is
not.

Fixing this whole situation is definitely part of the ongoing GC
cleanups that need to happen, probably before 1.0.

--Andrew Whitworth
_______________________________________________
http://lists.parrot.org/mailman/listinfo/parrot-dev

Andy Dougherty

unread,
Feb 3, 2009, 3:31:53 PM2/3/09
to Mark Glines, parro...@lists.parrot.org

I'm not sure. I'd think that replacing it by the actual assembly language
commands would work, however. Something like the patch below, perhaps.
asm("flushw") ought to work as well on 64-bit as it does on 32-bit. (I
don't have a sparcv9 to test this on, however.)

I can verify that for sparcv8 using the asm("ta 3") command doesn't change
the output of 'make coretest' in any significant way. However, also
commenting out the asm("ta 3") and just doing *nothing* also doesn't
change the output in any significant way, so I don't know how to really
test any of this.


--- parrot-svn/src/gc/system.c Tue Feb 3 13:34:22 2009
+++ parrot-andy/src/gc/system.c Tue Feb 3 13:49:11 2009
@@ -1,10 +1,10 @@
/*
Copyright (C) 2001-2008, The Perl Foundation.
-$Id: system.c 36325 2009-02-03 16:41:34Z whiteknight $
+$Id: system.c 36260 2009-02-01 21:36:47Z whiteknight $

=head1 NAME

-src/gc/system.c - CPU-dependent mark/sweep functions
+src/cpu_dep.c - CPU-dependent functions

=head1 DESCRIPTION

@@ -62,27 +62,12 @@
ASSERT_ARGS(trace_system_areas)
{
#if defined(__sparc)
- /* Flush the register windows. For sparc systems, we use hand-coded
- assembly language to create a small function that flushes the
- register windows. Store the code in a union with a double to
- ensure proper memory alignment. */
- static union {
- unsigned int insns[4];
- double align_hack[2];
- } u = { {
+ /* Flush the register windows. */
# ifdef __sparcv9
- 0x81580000, /* flushw */
+ asm("flushw");
# else
- 0x91d02003, /* ta ST_FLUSH_WINDOWS */
+ asm("ta 3"); /* ta ST_FLUSH_WINDOWS */
# endif
- 0x81c3e008, /* retl */
- 0x01000000 /* nop */
- } };
-
- /* Turn the array of machine code values above into a function pointer.
- Call the new function pointer to flush the register windows. */
- static void (*fn_ptr)(void) = (void (*)(void))&u.align_hack[0];
- fn_ptr();

#elif defined(__ia64__)

--
Andy Dougherty doug...@lafayette.edu
_______________________________________________
http://lists.parrot.org/mailman/listinfo/parrot-dev

Reply all
Reply to author
Forward
0 new messages