axp.h

Go to the documentation of this file.
00001 /*
00002  * QuickThreads -- Threads-building toolkit.
00003  * Copyright (c) 1993 by David Keppel
00004  *
00005  * Permission to use, copy, modify and distribute this software and
00006  * its documentation for any purpose and without fee is hereby
00007  * granted, provided that the above copyright notice and this notice
00008  * appear in all copies.  This software is provided as a
00009  * proof-of-concept and for demonstration purposes; there is no
00010  * representation about the suitability of this software for any
00011  * purpose.
00012  */
00013 
00014 #ifndef QUICKTHREADS_AXP_H
00015 #define QUICKTHREADS_AXP_H
00016 
00017 #define QUICKTHREADS_GROW_DOWN
00018 
00019 typedef unsigned long qt_word_t;
00020 
00021 
00022 /* Stack layout on the Alpha:
00023 
00024    Integer:
00025 
00026      Caller-save: r0..r8, r22..r25, r27..r29
00027      argument/caller-save: r16..r21
00028      callee-save: r9..r15
00029      return pc *callee-save*: r26
00030      stack pointer: r30
00031      zero: r31
00032 
00033    Floating-point:
00034 
00035      Caller-save: f0..f1, f10..f15
00036      argument/caller-save: f16..f21, f22..f30
00037      callee-save: f2..f9
00038      zero: f31
00039 
00040    Non-varargs:
00041 
00042    +---
00043    | padding
00044    | f9
00045    | f8
00046    | f7
00047    | f6
00048    | f5
00049    | f4
00050    | f3
00051    | f2
00052    | r26
00053    +---
00054    | padding
00055    | r29
00056    | r15
00057    | r14
00058    | r13
00059    | r12    on startup === `only'
00060    | r11    on startup === `userf'
00061    | r10    on startup === `qt'
00062    | r9     on startup === `qu'
00063    | r26    on startup === qt_start     <--- qt.sp
00064    +---
00065 
00066    Conventions for varargs startup:
00067 
00068    |  :
00069    | arg6
00070    | iarg5
00071    |  :
00072    | iarg0
00073    | farg5
00074    |  :
00075    | farg0
00076    +---
00077    | padding
00078    | r29
00079    | r15
00080    | r14
00081    | r13
00082    | r12    on startup === `startup'
00083    | r11    on startup === `vuserf'
00084    | r10    on startup === `cleanup'
00085    | r9     on startup === `qt'
00086    | r26    on startup === qt_vstart    <--- qt.sp
00087    +---
00088 
00089    Note: this is a pretty cheap/sleazy way to get things going,
00090    but ``there must be a better way.''  For instance, some varargs
00091    parameters could be loaded in to integer registers, or the return
00092    address could be stored on top of the stack. */
00093 
00094 
00095 /* Stack must be 16-byte aligned. */
00096 #define QUICKTHREADS_STKALIGN   (16)
00097 
00098 /* How much space is allocated to hold all the crud for
00099    initialization: 7 registers times 8 bytes/register. */
00100 
00101 #define QUICKTHREADS_STKBASE    (10 * 8)
00102 #define QUICKTHREADS_VSTKBASE   QUICKTHREADS_STKBASE
00103 
00104 
00105 /* Offsets of various registers. */
00106 #define QUICKTHREADS_R26    0
00107 #define QUICKTHREADS_R9 1
00108 #define QUICKTHREADS_R10    2
00109 #define QUICKTHREADS_R11    3
00110 #define QUICKTHREADS_R12    4
00111 
00112 
00113 /* When a never-before-run thread is restored, the return pc points
00114    to a fragment of code that starts the thread running.  For
00115    non-vargs functions, it just calls the client's `only' function.
00116    For varargs functions, it calls the startup, user, and cleanup
00117    functions.
00118 
00119    The varargs startup routine always reads 12 8-byte arguments from
00120    the stack.  If fewer argumets were pushed, the startup routine
00121    would read off the top of the stack.  To prevent errors we always
00122    allocate enough space.  When there are fewer args, the preallocated
00123    words are simply wasted. */
00124 
00125 extern void qt_start(void);
00126 #define QUICKTHREADS_ARGS_MD(sp)    (QUICKTHREADS_SPUT (sp, QUICKTHREADS_R26, qt_start))
00127 
00128 
00129 /* The AXP uses a struct for `va_list', so pass a pointer to the
00130    struct.  This may break some uses of `QUICKTHREADS_VARGS', but then we never
00131    claimed it was totally portable. */
00132 
00133 typedef void (qt_function_t)(void);
00134 
00135 struct qt_t;
00136 struct va_list;
00137 extern struct qt_t *qt_vargs (struct qt_t *sp, int nbytes,
00138                   struct va_list *vargs, void *pt,
00139                   qt_function_t *startup,
00140                   qt_function_t *vuserf,
00141                   qt_function_t *cleanup);
00142 
00143 #define QUICKTHREADS_VARGS(sp, nbytes, vargs, pt, startup, vuserf, cleanup) \
00144   (qt_vargs (sp, nbytes, (struct va_list *)(&(vargs)), pt, \
00145          (qt_function_t *) startup, (qt_function_t *)vuserf, \
00146          (qt_function_t *)cleanup));
00147 
00148 
00149 /* The *index* (positive offset) of where to put each value. */
00150 #define QUICKTHREADS_ONLY_INDEX (QUICKTHREADS_R12)
00151 #define QUICKTHREADS_USER_INDEX (QUICKTHREADS_R11)
00152 #define QUICKTHREADS_ARGT_INDEX (QUICKTHREADS_R10)
00153 #define QUICKTHREADS_ARGU_INDEX (QUICKTHREADS_R9)
00154 
00155 #define QUICKTHREADS_VCLEANUP_INDEX (QUICKTHREADS_R10)
00156 #define QUICKTHREADS_VUSERF_INDEX       (QUICKTHREADS_R11)
00157 #define QUICKTHREADS_VSTARTUP_INDEX (QUICKTHREADS_R12)
00158 #define QUICKTHREADS_VARGT_INDEX        (QUICKTHREADS_R9)
00159 
00160 #endif /* ndef QUICKTHREADS_AXP_H */

Generated on Wed Jan 21 15:32:10 2009 for SystemC by  doxygen 1.5.5