Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / verif / diag / assembly / include / c / stackinit_mt.s
/*
* ========== 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
* otherwise unspecified.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*
*
* ========== Copyright Header End ============================================
*/
#include "defines.h"
#define ZERO_OFFSET 48
!---------------------------------------------------
! Number of arguments passed to the diag
! We have a CONVENTION:
! argv[1] is THREAD ID
! argv[2] is number of threads
! argv[3] is USER DEFINED
! argv[4] is USER DEFINED
! currently we support up to argv[4]
!---------------------------------------------------
#ifndef C_ARGNUM
#define C_ARGNUM 5
#endif
#ifndef C_ARG3
#define C_ARG3 0
#endif
#ifndef C_ARG4
#define C_ARG4 0
#endif
!---------------------------------------------------
! stack pointer offset per Sparc V9 rules
!---------------------------------------------------
#define SP_OFFSET (STACKSIZE-4095)
!---------------------------------------------------
! some macros
!---------------------------------------------------
#define INIT_LOCAL_REGS \
set 0x0, %l0; \
set 0x0, %l1; \
set 0x0, %l2; \
set 0x0, %l3; \
set 0x0, %l4; \
set 0x0, %l5; \
set 0x0, %l6; \
set 0x0, %l7; \
set 0x0, %i0; \
set 0x0, %i1; \
set 0x0, %i2; \
set 0x0, %i3; \
set 0x0, %i4; \
set 0x0, %i5; \
set 0x0, %i6; \
set 0x0, %i7;
!---------------------------------------------------
!---------------------------------------------------
.section .text
!---------------------------------------------------
! the start of the C program
!---------------------------------------------------
.align 4
.global c_start
c_start:
!---------------------------------------------------
! register init - avoid mismatches in spill/fill traps
!---------------------------------------------------
ta T_CHANGE_PRIV
wrpr %g0, 0, %cwp
INIT_LOCAL_REGS
wrpr %g0, 1, %cwp
INIT_LOCAL_REGS
wrpr %g0, 2, %cwp
INIT_LOCAL_REGS
wrpr %g0, 3, %cwp
INIT_LOCAL_REGS
wrpr %g0, 4, %cwp
INIT_LOCAL_REGS
wrpr %g0, 5, %cwp
INIT_LOCAL_REGS
wrpr %g0, 6, %cwp
INIT_LOCAL_REGS
wrpr %g0, 7, %cwp
INIT_LOCAL_REGS
wrpr %g0, 0, %cwp
ta T_CHANGE_NONPRIV
!---------------------------------------------------
! set up stack per thread for all threads
!---------------------------------------------------
th_fork(prepare_thread, %l0);
changequote([, ])dnl
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.
!---------------------------------------------------
#ifndef SKIP_C_ARGS
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
call itos, 0
nop
setx [arg2t]eval(i*THREAD_STRIDE), %l0, %o0 ! a pointer to arg2tN
set THREAD_COUNT, %o1 ! arg2 is the thread count
call itos, 0
nop
setx [arg3t]eval(i*THREAD_STRIDE), %l0, %o0
set C_ARG3, %o1 ! USER defined
call itos, 0
nop
setx [arg4t]eval(i*THREAD_STRIDE), %l0, %o0
set C_ARG4, %o1 ! user defined
call itos, 0
nop
#endif
setx [stack]eval(i*THREAD_STRIDE), %l5, %sp
setx SP_OFFSET, %l0, %l1
add %sp, %l1, %sp ! set and adjust the stack pointer
#ifndef SKIP_C_ARGS
set C_ARGNUM, %o0 ! argc ! %o0 is argc
setx [argvp]eval(i*THREAD_STRIDE), %l0, %o1 ! %o1 is a ponter of array of arrays
#else
clr %o0
clr %o1
#endif
ba call_main ! now go to call_main...
nop
])dnl
changequote(`,')dnl'
!---------------------------------------
call_main: ! call the C program
#ifndef MAIN_INIT
setx main, %l0, %l1
#else
setx MAIN_INIT, %l0, %l1
#endif
jmpl %l1,%o7
nop
brnz %o0, c_fail
nop
c_pass:
ta T_GOOD_TRAP
nop
c_fail:
ta T_BAD_TRAP
nop
!--------------------------------------------------------------------------
!--------------------------------------------------------------------------
!--------------------------------------------------------------------------
!--------------------------------------------------------------------------
! 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){
! if(a ==0){
! s[0] = '0';
! s[1] = 0;
! return;
! }
! count = 0;
! result = a;
! while(result >0){
! hs[count++] = result % 10 + '0';
! result = result /10;
! }
! if(a<0) hs[count] = '-';
! else count--;
! for(iter= count; iter>=0; iter--) s[count-iter] = hs[iter];
! s[count+1] = 0;
!}
!--------------------------------------------------------------------------
itos:
mov %g0, %l7 ! count
brnz %o1, itos_proceed ! o1 is the number
nop
mov ZERO_OFFSET, %l0 ! number is 0
stb %l0, [%o0] ! return '0', 0
retl
stb %g0, [%o0 +1]
itos_proceed: ! check for sign
brgz %o1, itos_positive
nop
ba itos_while_entry
mulx %o1, -1, %i4
itos_positive:
mov %o1, %i4 ! result
itos_while_entry:
brgz %i4, itos_while_body
nop
ba itos_while_exit
nop
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
stb %l4, [%o2 + %l7]
mov %i3, %i4
inc %l7
ba itos_while_entry
nop
itos_while_exit:
brgz %o1, itos_positive2
nop
set 45, %i2 ! 45 is the value of the '-' character
stb %i2, [%o2 + %l7]
mov %g0, %l0
ba itos_for_entry
nop
itos_positive2:
dec %l7
mov %g0, %l0
itos_for_entry:
brgez %l7, itos_for_body
nop
ba itos_for_exit
nop
itos_for_body:
ldub [%o2 + %l7], %l4
stb %l4, [%o0 +%l0]
inc %l0
dec %l7
ba itos_for_entry
nop
itos_for_exit:
retl
stb %g0, [%o0 +%l0]
!--------------------------------------------------------------------------------------------
!--------------------------------------------------------------------------------------------
!--------------------------------------------------------------------------------------------
.section .data
.global shared_memory
shared_memory:
.skip 0x1000
.global shared_memory_buffers
shared_memory_buffers:
init_mem(0x0101010101010101, 8192, 8, +, 0, +, 0)
.skip 0xc000
.global barp
barp:
.skip 0x100
.global barrier_lock
barrier_lock:
.skip 0x100
changequote([, ])dnl
forloop([i], 0, eval(THREAD_COUNT-1), [
.global [argvp]eval(i*THREAD_STRIDE)
[argvp]eval(i*THREAD_STRIDE):
.xword arg0
.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)
.xword 0
.global [arg1t]eval(i*THREAD_STRIDE)
[arg1t]eval(i*THREAD_STRIDE):
.skip 128
.global [arg2t]eval(i*THREAD_STRIDE)
[arg2t]eval(i*THREAD_STRIDE):
.skip 128
.global [arg3t]eval(i*THREAD_STRIDE)
[arg3t]eval(i*THREAD_STRIDE):
.skip 128
.global [arg4t]eval(i*THREAD_STRIDE)
[arg4t]eval(i*THREAD_STRIDE):
.skip 128
.global [arg5t]eval(i*THREAD_STRIDE)
[arg5t]eval(i*THREAD_STRIDE):
.skip 128
.global [arg6t]eval(i*THREAD_STRIDE)
[arg6t]eval(i*THREAD_STRIDE):
.skip 128
.global [arg7t]eval(i*THREAD_STRIDE)
[arg7t]eval(i*THREAD_STRIDE):
.skip 128
.global [hs]eval(i*THREAD_STRIDE)
[hs]eval(i*THREAD_STRIDE):
.skip 128
])dnl
changequote(`,')dnl'
.global arg0
arg0:
.ascii "mycmain"
.byte 0
.global shm_sync
shm_sync:
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
!----------------------------------------------------------------------------------------------