* ========== Copyright Header Begin ==========================================
* OpenSPARC T2 Processor File: stackinit_mt.s
* Copyright (C) 1995-2007 Sun Microsystems, Inc. All Rights Reserved
* 4150 Network Circle, Santa Clara, California 95054, U.S.A.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* For the avoidance of doubt, and except that if any non-GPL license
* choice is available it will apply instead, Sun elects to use only
* the General Public License version 2 (GPLv2) at this time for any
* software where a choice of GPL license versions is made
* available with the language indicating that GPLv2 or any later version
* may be used, or where a choice of which version of the GPL is applied is
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* ========== Copyright Header End ============================================
!---------------------------------------------------
! Number of arguments passed to the diag
! argv[2] is number of threads
! argv[3] is USER DEFINED
! argv[4] is USER DEFINED
! currently we support up to argv[4]
!---------------------------------------------------
!---------------------------------------------------
! stack pointer offset per Sparc V9 rules
!---------------------------------------------------
#define SP_OFFSET (STACKSIZE-4095)
!---------------------------------------------------
!---------------------------------------------------
#define INIT_LOCAL_REGS \
!---------------------------------------------------
!---------------------------------------------------
!---------------------------------------------------
! the start of the C program
!---------------------------------------------------
!---------------------------------------------------
! register init - avoid mismatches in spill/fill traps
!---------------------------------------------------
!---------------------------------------------------
! set up stack per thread for all threads
!---------------------------------------------------
th_fork(prepare_thread, %l0);
forloop([i], 0, eval(THREAD_COUNT-1), [
[prepare_thread_]eval(i*THREAD_STRIDE):
!---------------------------------------------------
! Setting up the C args costs a fair bit, define SKIP_C_ARGS to skip this.
!---------------------------------------------------
setx [hs]eval(i*THREAD_STRIDE), %l0, %o2 ! pointer to help string per thread
setx [arg1t]eval(i*THREAD_STRIDE), %l0, %o0 ! a pointer to arg1tN
set eval(i*THREAD_STRIDE), %o1 ! arg1 is the thread ID
setx [arg2t]eval(i*THREAD_STRIDE), %l0, %o0 ! a pointer to arg2tN
set THREAD_COUNT, %o1 ! arg2 is the thread count
setx [arg3t]eval(i*THREAD_STRIDE), %l0, %o0
set C_ARG3, %o1 ! USER defined
setx [arg4t]eval(i*THREAD_STRIDE), %l0, %o0
set C_ARG4, %o1 ! user defined
setx [stack]eval(i*THREAD_STRIDE), %l5, %sp
add %sp, %l1, %sp ! set and adjust the stack pointer
set C_ARGNUM, %o0 ! argc ! %o0 is argc
setx [argvp]eval(i*THREAD_STRIDE), %l0, %o1 ! %o1 is a ponter of array of arrays
ba call_main ! now go to call_main...
!---------------------------------------
call_main: ! call the C program
!--------------------------------------------------------------------------
!--------------------------------------------------------------------------
!--------------------------------------------------------------------------
!--------------------------------------------------------------------------
! the itos - integer to string function below - is implemented in assembly
! based on the C implementation in the comments
!--------------------------------------------------------------------------
!void itos (char *s, int a){
! hs[count++] = result % 10 + '0';
! if(a<0) hs[count] = '-';
! for(iter= count; iter>=0; iter--) s[count-iter] = hs[iter];
!--------------------------------------------------------------------------
brnz %o1, itos_proceed ! o1 is the number
mov ZERO_OFFSET, %l0 ! number is 0
stb %l0, [%o0] ! return '0', 0
itos_proceed: ! check for sign
brgz %i4, itos_while_body
sdivx %i4, 10, %i3 ! divide by 10
sllx %i3, 2, %i5 ! multiply result by 4
add %i5, %i3, %i5 ! add it once -> multipy by 5 by now.
add %i5, %i5, %i5 ! multiply by 10 overall
sub %i4, %i5, %l4 ! l4 is the remainder now.
add %l4, ZERO_OFFSET, %l4
set 45, %i2 ! 45 is the value of the '-' character
!--------------------------------------------------------------------------------------------
!--------------------------------------------------------------------------------------------
!--------------------------------------------------------------------------------------------
.global shared_memory_buffers
init_mem(0x0101010101010101, 8192, 8, +, 0, +, 0)
forloop([i], 0, eval(THREAD_COUNT-1), [
.global [argvp]eval(i*THREAD_STRIDE)
[argvp]eval(i*THREAD_STRIDE):
.xword [arg1t]eval(i*THREAD_STRIDE)
.xword [arg2t]eval(i*THREAD_STRIDE)
.xword [arg3t]eval(i*THREAD_STRIDE)
.xword [arg4t]eval(i*THREAD_STRIDE)
.xword [arg5t]eval(i*THREAD_STRIDE)
.xword [arg6t]eval(i*THREAD_STRIDE)
.xword [arg7t]eval(i*THREAD_STRIDE)
.global [arg1t]eval(i*THREAD_STRIDE)
[arg1t]eval(i*THREAD_STRIDE):
.global [arg2t]eval(i*THREAD_STRIDE)
[arg2t]eval(i*THREAD_STRIDE):
.global [arg3t]eval(i*THREAD_STRIDE)
[arg3t]eval(i*THREAD_STRIDE):
.global [arg4t]eval(i*THREAD_STRIDE)
[arg4t]eval(i*THREAD_STRIDE):
.global [arg5t]eval(i*THREAD_STRIDE)
[arg5t]eval(i*THREAD_STRIDE):
.global [arg6t]eval(i*THREAD_STRIDE)
[arg6t]eval(i*THREAD_STRIDE):
.global [arg7t]eval(i*THREAD_STRIDE)
[arg7t]eval(i*THREAD_STRIDE):
.global [hs]eval(i*THREAD_STRIDE)
[hs]eval(i*THREAD_STRIDE):
!----------------------------------------------------------------------------------------------