• Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • File List
  • Globals

sst/elements/genericProc/programs/ppcPimCalls.h

00001 #ifndef PPCPIMCALLS_H
00002 #define PPCPIMCALLS_H
00003 
00004 #include "pimSysCallDefs.h"
00005 #include "pimSysCallTypes.h"
00006 
00007 #define _INLINE_ static inline
00008 
00009 /* 
00010    GCC assembly style:
00011    asm volatile("" : <output reg> : <input reg> : <clobbered reg> )
00012 */
00013 #define SYSCALL(call, result) __asm__ volatile ( \
00014         "li r0, %1\n\t" /* Set to syscall */ \
00015         "sc\n\t" /*make the sys call*/ \
00016         "mr %0, r3\n" /*collect results*/ \
00017         : "=r" (result) \
00018         : "K" (call) \
00019         : "r0", "r3");
00020 #define VOID_SYSCALL(call) __asm__ volatile ( \
00021         "li r0, %0\n" /* set the syscall */ \
00022         "sc" /* make the call */ \
00023         ::"K"(call) /* K means "unsigned 16-bit constant" */ \
00024         :"r0");
00025 #define ONE_ARG_SYSCALL(call, arg, result) __asm__ volatile ("mr r3, %1\n" /* a */ \
00026         "li r0, %2\n" /* set the syscall */ \
00027         "sc\n" /* make the call */ \
00028         "mr %0, r3" /* collect results */ \
00029         : "=r" (result) \
00030         :"r"(arg), "K"(call) /* K means "unsigned 16-bit constant" */ \
00031         :"r0","r3","memory")
00032 #define ONE_ARG_VOID_SYSCALL(call, arg) __asm__ volatile ("mr r3, %0\n" /* a */ \
00033         "li r0, %1\n" /* set the syscall */ \
00034         "sc" /* make the call */ \
00035         ::"r"(arg), "K"(call) /* K means "unsigned 16-bit constant" */ \
00036         :"r0","r3","memory")
00037 #define TWO_ARG_SYSCALL(call, arg1, arg2, result) __asm__ volatile ("mr r3, %1\n" /* arg1 */ \
00038                 "mr r4, %2\n" /* arg2 */ \
00039                 "li r0, %3\n"/*Set syscall*/ \
00040                 "sc\n" /* make the "system call" */ \
00041                 "mr %0, r3\n" /* Collect results*/ \
00042                 : "=r" (result) \
00043                 : "r" (arg1), "r" (arg2), "K"(call) \
00044                 : "r0", "r3", "r4", "memory");
00045 #define TWO_ARG_VOID_SYSCALL(call, arg1, arg2) __asm__ volatile ("mr r3, %0\n" /* arg1 */ \
00046                 "mr r4, %1\n" /* arg2 */ \
00047                 "li r0, %2\n"/*Set syscall*/ \
00048                 "sc" /* make the "system call" */ \
00049                 :: "r" (arg1), "r" (arg2), "K"(call) \
00050                 : "r0", "r3", "r4", "memory");
00051 
00052 //: Send a pagerank iteration to memory
00053 //
00054 // A failure (return 0) indicates a need to retry
00055 _INLINE_ int PIM_PageRank(const int begin, const int end, const int i,
00056                           unsigned int *types, unsigned int *fh, 
00057                           unsigned int *rev_end_points, void *rinfo) {
00058   int result;
00059   asm volatile ("mr r3, %1\n" /* begin */
00060                 "mr r4, %2\n" /* end */
00061                 "mr r5, %3\n" /* i */
00062                 "mr r6, %4\n" /* types */
00063                 "mr r7, %5\n" /* fh */
00064                 "mr r8, %6\n" /* rev_end_points */
00065                 "mr r9, %7\n" /* rinfo */
00066                 "li r0, %8\n" /* set syscall */
00067                 "sc\n" /* make syscall */
00068                 "mr %0, r3, 0\n" /* Collect results */
00069                 : "=r" (result)
00070                 : "r" (begin), "r" (end), "r" (i), "r" (types), "r" (fh),
00071                   "r" (rev_end_points), "r" (rinfo), "K" (SS_PIM_PAGERANK)
00072                 : "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", 
00073                 "memory");
00074   return result;
00075 }
00076 
00077 //: Send a force computation to memory
00078 //
00079 // A failure (return 0) indicates a need to retry
00080 _INLINE_ int PIM_ForceCalc(const int j, const int i, double *af, 
00081                            const double *ax,
00082                            const double *cutforce,
00083                            const int numneigh) {
00084   int result;
00085   asm volatile ("mr r3, %1\n" /* j */
00086                 "mr r4, %2\n" /* i */
00087                 "mr r5, %3\n" /* af */
00088                 "mr r6, %4\n" /* ax */
00089                 "mr r7, %5\n" /* cutforce */
00090                 "mr r8, %6\n" /* numneigh */
00091                 "li r0, %7\n" /* set syscall */
00092                 "sc\n" /* make the "system call" */
00093                 "mr %0, r3, 0\n" /* Collect results*/
00094                 : "=r" (result)
00095                 : "r" (j), "r" (i), "r" (af), "r" (ax), "r" (cutforce), 
00096                   "r" (numneigh), "K" (SS_PIM_FORCE_CALC)
00097                 : "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "memory");
00098   return result;
00099 }
00100 
00101 //: Check the number of outstanding advanced memory requests
00102 _INLINE_ int PIM_OutstandingMR() {
00103   int result;
00104   asm volatile ("li r0, %1\n" /* set syscall */
00105                 "sc\n" /* make the "system call" */
00106                 "mr %0, r3, 0\n" /* Collect results*/
00107                 : "=r" (result)
00108                 : "K"  (SS_PIM_ADV_OUT)
00109                 : "r0", "r3", "memory" );
00110   return result;
00111 }
00112 
00113 //: Send a matrix-vector operation to memory
00114 //
00115 // A failure (return 0) indicates a need to retry
00116 _INLINE_ int PIM_MatVec(int start, int end, const double *cur_vals, 
00117                         const double *x, const int *cur_inds, double *sum) {
00118   int result;
00119   asm volatile ("mr r3, %1\n" /* start */
00120                 "mr r4, %2\n" /* end */
00121                 "mr r5, %3\n" /* cur_vals */
00122                 "mr r6, %4\n" /* x */
00123                 "mr r7, %5\n" /* cur_inds */
00124                 "mr r8, %6\n" /* sum */
00125                 "li r0, %7\n" /* set syscall */
00126                 "sc\n" /* make the "system call" */
00127                 "mr %0, r3, 0\n" /* Collect results*/
00128                 : "=r" (result)
00129                 : "r" (start), "r" (end), "r" (cur_vals), "r" (x), "r" (cur_inds), "r" (sum),
00130                 "K" (SS_PIM_MATVEC)
00131                 : "r0", "r3", "r4", "r5", "r6", "r7", "r8", "memory");
00132   return result;
00133 } 
00134 
00135 //: Send an Atomic Memory Operations to memory
00136 //
00137 // A failure (return 0) probably indicates a need to retry
00138 _INLINE_ int PIM_AMO(void *addr, PIM_amo_types op, int imm)
00139 {
00140   int result;
00141   asm volatile ("mr r3, %1\n" /* addr */
00142                 "mr r4, %2\n" /* operation */
00143                 "mr r5, %3\n" /* immediate value */
00144                 "li r0, %4\n" /* Set to syscall */
00145                 "sc\n" /* make the "system call" */
00146                 "mr %0, r3, 0\n" /* Collect results*/
00147                 : "=r" (result)
00148                 : "r" (addr), "r" (op), "r" (imm), "K"(SS_PIM_AMO)
00149                 : "r0", "r3", "r4", "r5", "memory");
00150   return result;
00151 }
00152 
00153 //:Fork a new thread (DEPRECATED)
00154 //
00155 // Wrapper around the pim system call. The new function DOES NOT recieve its
00156 // own private stack; that must be set-up ahead of time. If you want a stack,
00157 // try PIM_loadAndSpawnToLocaleStack().
00158 //
00159 //!in: start_routine: Address of the function where the new function will begin execution.
00160 //!in: arg: a void* argument which may be passed to the new function
00161 _INLINE_ int PIM_threadCreate(void* start_routine, void* arg)
00162 {
00163   int result;
00164   TWO_ARG_SYSCALL(SS_PIM_FORK, start_routine, arg, result);
00165   return result;
00166 }
00167 
00168 //:Fork a new thread
00169 //
00170 // Wrapper around the pim system call. The new function DOES NOT recieve its
00171 // own private stack; that must be set-up ahead of time. If you want a stack,
00172 // try PIM_loadAndSpawnToLocaleStack().
00173 //
00174 //!in: start_routine: Address of the function where the new function will begin execution.
00175 //!in: arg: a void* argument which may be passed to the new function
00176 //!in: stack: a stack pointer for the new thread (remember, PPC stacks grow DOWN)
00177 _INLINE_ int PIM_threadCreateWithStack(void* start_routine, void* arg, void* stack)
00178 {
00179     int result;
00180     asm volatile (
00181             "mr r5, r1\n\t" /* save the stack */
00182             "mr r1, %3\n\t" /* replace the stack with the new one */
00183             "mr r3, %1\n\t" /* Where execution begins */
00184             "mr r4, %2\n\t" /* What arguments */
00185             "li r0, %4\n\t" /* Set to syscall */
00186             "sc\n\t" /* make the "system call" */
00187             "mr %0, r3, 0\n\t" /* Collect results*/
00188             "mr r1, r5\n" /* resurrect the stack */
00189             : "=r" (result)
00190             : "r" (start_routine), "r" (arg), "r" (stack), "K"(SS_PIM_FORK)
00191             : "r0", "r3", "r4", "r5");
00192     return result;
00193 }
00194 
00195 //: Spawn to a coprocessor 
00196 //
00197 // Wrapper around the pim system call. spawns a thread to begin on a
00198 // coprocessor, such as a NIC or PIM. Returns a thread ID. 
00199 //
00200 //!in: coProc: coprocessor number. 0 for main processor, 1 for NIC, see pimSysCallTypes.h for full list/enum
00201 //!in: start_routine: Address of the function where the spawned thread will begin
00202 //!in: arg: a void& argument when may be passed to the new function
00203 _INLINE_ int PIM_spawnToCoProc(PIM_coProc coProc, void* start_routine,
00204                                void* arg)
00205 {
00206   int result;
00207   asm volatile ("mr r3, %1\n" /* coprocessor to handle thread */
00208                 "mr r4, %2\n" /* Where execution begins */
00209                 "mr r5, %3\n" /* What arguments */
00210                 "li r0, %4\n" /* Set to syscall */
00211                 "sc\n" /* make the "system call" */
00212                 "mr %0, r3\n" /* Collect results*/
00213                 : "=r" (result)
00214                 : "r" (coProc), "r" (start_routine), "r" (arg), "K"(SS_PIM_SPAWN_TO_COPROC)
00215                 : "r0", "r3", "r4", "r5");
00216   return result;
00217 }
00218 
00219 //: Spawn to a coprocessor
00220 //
00221 // Wrapper around the pim system call. Spawns a thread to begin on a
00222 // coprocessor, such as a NIC or PIM. Returns a thread ID.
00223 //
00224 //!in: coProc: coprocessor number. 0 for main processor, 1 for NIC, see pimSysCallTypes.h for full list/enum
00225 //!in: start_routine: Address of the function where the spawned thread will begin
00226 //!in: arg: a void* argument when may be passed to the new function
00227 //!in: stack: a stack pointer for the new thread (remember, PPC stacks grow DOWN)
00228 _INLINE_ int PIM_spawnToCoProcWithStack(PIM_coProc coProc,
00229                                         void* start_routine,
00230                                         void* arg, void* stack)
00231 {
00232     int result;
00233     asm volatile (
00234             "mr r6, r1\n\t" /* save the stack */
00235             "mr r1, %4\n\t" /* replae the stack with the new one */
00236             "mr r3, %1\n\t" /* coprocessor to handle thread */
00237             "mr r4, %2\n\t" /* Where execution begins */
00238             "mr r5, %3\n\t" /* What arguments */
00239             "li r0, %5\n\t" /* Set to syscall */
00240             "sc\n\t" /* make the "system call" */
00241             "mr %0, r3\n\t" /* Collect results*/
00242             "mr r1, r6\n" /* resurrect the old stack */
00243             : "=r" (result)
00244             : "r" (coProc), "r" (start_routine), "r" (arg), "r" (stack), "K"(SS_PIM_SPAWN_TO_COPROC)
00245             : "r0", "r3", "r4", "r5", "r6");
00246     return result;
00247 }
00248 
00249 //: Load registers and spawn to coproc
00250 //
00251 // Same as PIM_spawnToCoProcWithStack(), but allows more registers to be written
00252 _INLINE_ int PIM_loadAndSpawnToCoProcWithStack(PIM_coProc coProc,
00253                                     void* start_routine,
00254                                     void* r3Arg, void* r6Arg, void* r7Arg,
00255                                     void* r8Arg, void* r9Arg, void* stack)
00256 {
00257     int result;
00258     asm volatile (
00259             "mr r10, r1\n\t" /* save the stack */
00260             "mr r1, %8\n\t" /* replace the stack with the new one */
00261             "mr r3, %1\n\t" /* coprocessor to handle thread */
00262             "mr r4, %2\n\t" /* Where execution begins */
00263             "mr r5, %3\n\t" /* argument (ends up in r3) */
00264             "mr r6, %4\n\t" /* argument (ends up in r4) */
00265             "mr r7, %5\n\t" /* argument (ends up in r5) */
00266             "mr r8, %6\n\t" /* argument (ends up in r6) */
00267             "mr r9, %7\n\t" /* argument (ends up in r7) */
00268             "li r0, %9\n\t" /* Set to syscall */
00269             "sc\n\t" /* make the "system call" */
00270             "mr %0, r3\n\t" /* Collect results*/
00271             "mr r1, r10\n" /* resurrect the old stack */
00272             : "=r" (result)
00273             : "r" (coProc), "r" (start_routine), "r" (r3Arg), "r" (r6Arg),
00274             "r" (r7Arg), "r" (r8Arg), "r" (r9Arg), "r" (stack), "K"(SS_PIM_SPAWN_TO_COPROC)
00275             : "r0", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10");
00276     return result;
00277 }
00278 
00279 //: Load registers and spawn to coproc (DEPRECATED)
00280 //
00281 // Same as PIM_spawnToCoProc(), but allows more registers to be written
00282 _INLINE_ int PIM_loadAndSpawnToCoProc(PIM_coProc coProc, void* start_routine,
00283                                     void* r3Arg, void* r6Arg, void* r7Arg,
00284                                     void* r8Arg, void* r9Arg) {
00285   int result;
00286   asm volatile ("mr r3, %1\n" /* coprocessor to handle thread */
00287                 "mr r4, %2\n" /* Where execution begins */
00288                 "mr r5, %3\n" /* argument (ends up in r3) */
00289                 "mr r6, %4\n" /* argument (ends up in r4) */
00290                 "mr r7, %5\n" /* argument (ends up in r5) */
00291                 "mr r8, %6\n" /* argument (ends up in r6) */
00292                 "mr r9, %7\n" /* argument (ends up in r7) */
00293                 "li r0, %8\n" /* Set to syscall */
00294                 "sc\n" /* make the "system call" */
00295                 "mr %0, r3\n" /* Collect results*/
00296                 : "=r" (result)
00297                 : "r" (coProc), "r" (start_routine), "r" (r3Arg), "r" (r6Arg),
00298                   "r" (r7Arg), "r" (r8Arg), "r" (r9Arg), "K" (SS_PIM_SPAWN_TO_COPROC)
00299                 : "r0", "r3", "r4", "r5", "r6", "r7", "r8", "r9");
00300   return result;
00301 }
00302 
00303 //: Loads registers and spawns a thread to a given locale, with a stack
00304 //
00305 // Similar to PIM_loadAndSpawnToCoProc, but gives the thread a stack and
00306 // spawns to a memory locale rather than a device-type.
00307 // On success, it returns the threadID of the newly created thread.
00308 //
00309 // start_routine should be a function with a prototype similar to one of
00310 // the following:
00311 //         void func ();
00312 //         void func1 (arg);
00313 //         void func2 (arg1, arg2);
00314 //         void func3 (arg1, arg2, arg3);
00315 //         void func4 (arg1, arg2, arg3, arg4);
00316 //         void func5 (arg1, arg2, arg3, arg4, arg5);
00317 // The arguments are all passed in via the integer registers (r3, r4, etc.)
00318 // and so cannot be floating point values.
00319 _INLINE_ int PIM_loadAndSpawnToLocaleStack(int locale,
00320                                            void* start_routine, 
00321                                            void* r3Arg, void* r6Arg, 
00322                                            void* r7Arg, void* r8Arg, 
00323                                            void* r9Arg) {
00324   int result;
00325   asm volatile ("mr r3, %1\n" /* locale to handle thread */
00326                 "mr r4, %2\n" /* Where execution begins */
00327                 "mr r5, %3\n" /* argument (ends up in r3) */
00328                 "mr r6, %4\n" /* argument (ends up in r4) */
00329                 "mr r7, %5\n" /* argument (ends up in r5) */
00330                 "mr r8, %6\n" /* argument (ends up in r6) */
00331                 "mr r9, %7\n" /* argument (ends up in r7) */
00332                 "li r0, %8\n" /* Set to syscall */
00333                 "sc\n" /* make the "system call" */
00334                 "mr %0, r3\n" /* Collect results*/
00335                 : "=r" (result)                 
00336                 : "r" (locale), "r" (start_routine), "r" (r3Arg), "r" (r6Arg), 
00337                   "r" (r7Arg), "r" (r8Arg), "r" (r9Arg), "K"(SS_PIM_SPAWN_TO_LOCALE_STACK)
00338                 : "r0", "r3", "r4", "r5", "r6", "r7", "r8", "r9");
00339   return result;
00340 }
00341 
00342 //: Loads registers and creates a non-runnable thread on a given locale, with a stack
00343 //
00344 // Similar to PIM_loadAndSpawnToLocaleStack, except the thread is not runnable
00345 // and must be started by using PIM_startStoppedThread
00346 _INLINE_ int PIM_loadAndSpawnToLocaleStackStopped(int locale, void* start_routine,
00347                                         void* r3Arg, void* r6Arg, void* r7Arg,
00348                                         void* r8Arg, void* r9Arg)
00349 {
00350     int result;
00351     asm volatile (
00352             "mr r3, %1\n" /* coprocessor to handle thread */
00353             "mr r4, %2\n" /* Where execution begins */
00354             "mr r5, %3\n" /* argument (ends up in r3) */
00355             "mr r6, %4\n" /* argument (ends up in r4) */
00356             "mr r7, %5\n" /* argument (ends up in r5) */
00357             "mr r8, %6\n" /* argument (ends up in r6) */
00358             "mr r9, %7\n" /* argument (ends up in r7) */
00359             "li r0, %8\n" /* Set to syscall */
00360             "sc\n" /* make the "system call" */
00361             "mr %0, r3\n" /* Collect results */
00362             : "=r" (result)
00363             : "r" (locale), "r" (start_routine), "r" (r3Arg), "r" (r6Arg),
00364               "r" (r7Arg), "r" (r8Arg), "r" (r9Arg), "K"(SS_PIM_SPAWN_TO_LOCALE_STACK_STOPPED)
00365             : "r0", "r3", "r4", "r5", "r6", "r7", "r8", "r9");
00366     return result;
00367 }
00368 
00369 //: Makes a given thread runnable
00370 _INLINE_ int PIM_startStoppedThread(int tid, int shep)
00371 {
00372     int result;
00373     TWO_ARG_SYSCALL(SS_PIM_START_STOPPED_THREAD, tid, shep, result);
00374     return result;
00375 }
00376 
00377 _INLINE_ int PIM_switchAddrMode(PIM_addrMode mode)
00378 {
00379     int result;
00380     ONE_ARG_SYSCALL(SS_PIM_SWITCH_ADDR_MODE, mode, result);
00381     return result;
00382 }
00383 
00384 //Fast buffer read
00385 //: Quickly get a buffer full of data from a file
00386 //: return number of bytes read
00387 _INLINE_ unsigned int PIM_fastFileRead (char * filename_addr, 
00388                                     void * buf_addr,
00389                                     unsigned int maxBytes,
00390                                     unsigned int offset) 
00391 {
00392   unsigned int bytes = 0;
00393   asm volatile ("mr r3, %1\n" /* store pointer to file name */
00394                 "mr r4, %2\n" /* store pointer to buffer */
00395                 "mr r5, %3\n" /* store max bytes to read */
00396                 "mr r6, %4\n" /* store offset in file to read from */
00397                 "li r0, %5\n" /* Set to syscall */
00398                 "sc\n" /* make the call */
00399                 "mr %0, r3\n" /* Collect length of data read */
00400                 : "=r" (bytes)
00401                 : "r" (filename_addr), "r" (buf_addr), "r" (maxBytes), "r" (offset), "K"(SS_PIM_FFILE_RD)
00402                 : "r0", "r3", "r4", "r5", "r6", "memory" );
00403   return bytes;
00404 }
00405 
00406 //:Malloc memory
00407 //
00408 // Wrapper around the malloc system call which returns an address
00409 // where the memory was allocated
00410 
00411 #define ALLOC_GLOBAL     0
00412 #define ALLOC_LOCAL_ADDR 1
00413 #define ALLOC_LOCAL_ID   2
00414 
00415 _INLINE_ void* PIM_alloc(const unsigned int size, const unsigned int type, const unsigned int opt)
00416 {
00417     register unsigned int result;
00418     asm volatile ("mr r3, %1\n" /* size */
00419                   "mr r4, %2\n" /* allocate type */
00420                   "mr r5, %3\n" /* send option */
00421                   "li r0, %4\n" /* Set to syscall */
00422                   "sc\n" /* make the syscall */
00423                   "mr %0, r3\n" /* collect the results */
00424                   : "=r" (result)
00425                   : "r" (size), "r" (type), "r" (opt), "K"(SS_PIM_MALLOC)
00426                   : "r0", "r3", "r4", "r5", "memory");
00427     return (void*)result;
00428 }
00429 
00430 _INLINE_ void* PIM_globalMalloc(const unsigned int size)
00431 {
00432     return PIM_alloc(size, ALLOC_GLOBAL, 0);
00433 }
00434 
00435 _INLINE_ void* PIM_localMallocNearAddr(const unsigned int size, const void * addr)
00436 {
00437     return PIM_alloc(size, ALLOC_LOCAL_ADDR, (unsigned int)addr);
00438 }
00439 
00440 _INLINE_ void* PIM_localMallocAtID(const unsigned int size, const unsigned int ID)
00441 {
00442     return PIM_alloc(size, ALLOC_LOCAL_ID, ID);
00443 }
00444 
00445 _INLINE_ void* PIM_fastMalloc(unsigned int size)
00446 {
00447   unsigned int result;
00448   asm volatile ("lwz r3, %1\n" /* size */
00449                 "li r4, 0\n" /*allocate in heap area*/
00450                 "li r0, %2\n" /* Set to syscall */
00451                 "sc\n" /* make the "system call" */
00452                 "mr %0, r3\n" /* Collect results*/
00453                 : "=r" (result)
00454                 : "m" (size), "K"(SS_PIM_MALLOC)
00455                 : "r0", "r3", "r4", "memory");
00456   return (void*)result;
00457 }
00458 
00459 //:Malloc stack memory
00460 //
00461 // Wrapper around the malloc system call which returns an address
00462 // where the memory was allocated - should only be used for thread
00463 // stack creation
00464 
00465 _INLINE_ void* PIM_fastStackMalloc(unsigned int size)
00466 {
00467   unsigned int result;
00468   asm volatile ("lwz r3, %1\n" /* size */
00469                 "li r4, 1\n" /*allocate in stack area*/
00470                 "li r0, %2\n" /* Set to syscall */
00471                 "sc\n" /* make the "system call" */
00472                 "mr %0, r3\n" /* Collect results*/
00473                 : "=r" (result)
00474                 : "m" (size), "K"(SS_PIM_MALLOC)
00475                 : "r0", "r3", "r4", "memory");
00476   return (void*)result;
00477 }
00478 
00479 //:Malloc memory
00480 //
00481 // Wrapper around the malloc system call which returns an address
00482 // where the memory was allocated
00483 
00484 _INLINE_ unsigned int PIM_fastFreeSize(void *ptr, unsigned int size)
00485 {
00486   unsigned int result;
00487   unsigned int addr = (unsigned int)ptr;
00488   asm volatile ("lwz r3, %1\n" /* ptr */
00489                 "lwz r4, %2\n" /* size */
00490                 "li r0, %3\n" /* Set to syscall */
00491                 "sc\n" /* make the "system call" */
00492                 "mr %0, r3\n" /* Collect results*/
00493                 : "=r" (result)
00494                 : "m" (addr), "m" (size), "K"(SS_PIM_FREE)
00495                 : "r0", "r3", "r4", "memory");
00496 
00497   return result;
00498 }
00499 
00500 //: Write directly to memory
00501 //
00502 // Bypasses cache and other mechanisms
00503 _INLINE_ void PIM_writeMem(unsigned int *addr, unsigned int data) {
00504     TWO_ARG_VOID_SYSCALL(SS_PIM_WRITE_MEM, addr, data);
00505 }
00506 
00507 _INLINE_ unsigned int PIM_fastFree(void *ptr) 
00508 {
00509   unsigned int size = 0;
00510   return PIM_fastFreeSize (ptr, size);
00511 }
00512 
00513 _INLINE_ unsigned int PIM_hwRand(void)
00514 {
00515   unsigned int result;
00516   SYSCALL(SS_PIM_RAND, result);
00517   return result;
00518 }
00519 
00520 _INLINE_ int PIM_quickPrint(unsigned int a, unsigned int b, unsigned int c)
00521 {
00522  int result;
00523  asm volatile ("mr r3, %1\n" /* a */
00524                "mr r4, %2\n" /* b */
00525                "mr r5, %3\n" /* c */
00526                "li r0, %4\n" /* Set to syscall */
00527                "sc\n" /* make the "system call" */
00528                "mr %0, r3\n" /* Collect results*/
00529                : "=r" (result)
00530                : "r" (a), "r" (b), "r" (c), "K"(SS_PIM_QUICK_PRINT)
00531                : "r0", "r3", "r4", "r5", "memory");
00532   return result;
00533 }
00534 
00535 _INLINE_ int PIM_trace(unsigned int a, unsigned int b, unsigned int c)
00536 {
00537  int result;
00538  asm volatile ("mr r3, %1\n" /* a */
00539                "mr r4, %2\n" /* b */
00540                "mr r5, %3\n" /* c */
00541                "li r0, %4\n" /* Set to syscall */
00542                "sc\n" /* make the "system call" */
00543                "mr %0, r3\n" /* Collect results*/
00544                : "=r" (result)
00545                : "r" (a), "r" (b), "r" (c), "K"(SS_PIM_TRACE)
00546                : "r0", "r3", "r4", "r5");
00547   return result;
00548 }
00549 
00550 /* This provides a sort of virtual-memory-esque trick. A good way to think
00551  * about it is as a remapping. One region of memory (starting at vstart and
00552  * continuing for size bytes) is remapped to another region (starting at kstart
00553  * and continuing for size bytes). This region is treated with the cache
00554  * characteristics indicated by cached.
00555  *
00556  * NOTE: This is specific to the processor. So, for example, in a PIM context,
00557  * only the PIM that ran this syscall will be aware of the mapping. */
00558 _INLINE_ int PIM_mem_region_create(int region, void * vstart,
00559                 unsigned long size, void * kstart, int cached)
00560 {
00561  int result;
00562   asm volatile ("mr r3, %1\n" /* region */
00563                "mr r4, %2\n" /* vstart */
00564                "mr r5, %3\n" /* size */
00565                "mr r6, %4\n" /* kstart */
00566                "mr r7, %5\n" /* cached */
00567                "li r0, %6\n" /* Set to syscall */
00568                "sc\n" /* make the "system call" */
00569                "mr %0, r3\n" /* Collect results*/
00570                : "=r" (result)
00571                 : "r" (region), "r" (vstart), "r" (size), "r" (kstart), "r" (cached), "K"(SS_PIM_MEM_REGION_CREATE)
00572                 : "r0", "r3", "r4", "r5", "r6", "r7", "memory");
00573   return result;
00574 }
00575 
00576 _INLINE_ int PIM_mem_region_get(int region, unsigned long *addr,
00577                                         unsigned long *size )
00578 {
00579  int result;
00580   asm volatile ("mr r3, %1\n" /* region */
00581                "mr r4, %2\n" /* addr */
00582                "mr r5, %3\n" /* size */
00583                "li r0, %4" /* Set to syscall */
00584                "sc\n" /* make the "system call" */
00585                "mr %0, r3\n" /* Collect results*/
00586                : "=r" (result)
00587                 : "r" (region), "r" (addr), "r" (size), "K"(SS_PIM_MEM_REGION_GET)
00588                 : "r0", "r3", "r4", "r5", "memory");
00589   return result;
00590 }
00591 
00592 _INLINE_ void PIM_writeSpecial(PIM_cmd c, unsigned int v1)
00593 {
00594   asm volatile ("mr r3, %0\n" /* c */
00595                "mr r4, %1\n" /* v1 */
00596                "li r0, %2\n" /* Set to syscall */
00597                "sc\n" /* make the "system call" */
00598                :
00599                : "r" (c), "r" (v1), "K"(SS_PIM_WRITE_SPECIAL)
00600                : "r0", "r3", "r4");
00601 }
00602 
00603 _INLINE_ void PIM_writeSpecial2(PIM_cmd c, unsigned int v1, unsigned int v2)
00604 {
00605   asm volatile ("mr r3, %0\n" /* c */
00606                "mr r4, %1\n" /* v1 */
00607                "mr r5, %2\n" /* v2 */
00608                "li r0, %3\n" /* Set to syscall */
00609                "sc\n" /* make the "system call" */
00610                :
00611                : "r" (c), "r" (v1), "r" (v2), "K"(SS_PIM_WRITE_SPECIAL2)
00612                : "r0", "r3", "r4", "r5");
00613 }
00614 
00615 _INLINE_ void PIM_writeSpecial3(PIM_cmd c, unsigned int v1, unsigned int v2,
00616                               unsigned int v3)
00617 {
00618   asm volatile ("mr r3, %0\n" /* c */
00619                "mr r4, %1\n" /* v1 */
00620                "mr r5, %2\n" /* v2 */
00621                "mr r6, %3\n" /* v3 */
00622                "li r0, %4\n" /* Set to syscall */
00623                "sc\n" /* make the "system call" */
00624                 :
00625                 : "r" (c), "r" (v1), "r" (v2), "r" (v3), "K"(SS_PIM_WRITE_SPECIAL3)
00626                 : "r0", "r3", "r4", "r5", "r6");
00627 }
00628 
00629 _INLINE_ void PIM_writeSpecial4(PIM_cmd c, unsigned int v1, unsigned int v2,
00630                                 unsigned int v3, unsigned int v4)
00631 {
00632   asm volatile ("mr r3, %0\n" /* c */
00633                "mr r4, %1\n" /* v1 */
00634                "mr r5, %2\n" /* v2 */
00635                "mr r6, %3\n" /* v3 */
00636                "mr r7, %4\n" /* v4 */
00637                "li r0, %5\n" /* Set to syscall */
00638                "sc\n" /* make the "system call" */
00639                 :
00640                 : "r" (c), "r" (v1), "r" (v2), "r" (v3), "r" (v4), "K"(SS_PIM_WRITE_SPECIAL4)
00641                 : "r0", "r3", "r4", "r5", "r6", "r7");
00642 }
00643 
00644 _INLINE_ void PIM_writeSpecial5(PIM_cmd c, unsigned int v1, unsigned int v2,
00645                               unsigned int v3, unsigned int v4,
00646                               unsigned int v5)
00647 {
00648   asm volatile ("mr r3, %0\n" /* c */
00649                "mr r4, %1\n" /* v1 */
00650                "mr r5, %2\n" /* v2 */
00651                "mr r6, %3\n" /* v3 */
00652                "mr r7, %4\n" /* v4 */
00653                "mr r8, %5\n" /* v5 */
00654                "li r0, %6\n" /* Set to syscall */
00655                "sc\n" /* make the "system call" */
00656                 :
00657                 : "r" (c), "r" (v1), "r" (v2), "r" (v3), "r" (v4), "r" (v5), "K"(SS_PIM_WRITE_SPECIAL5)
00658                 : "r0", "r3", "r4", "r5", "r6", "r7", "r8");
00659 }
00660 
00661 _INLINE_ void PIM_writeSpecial6(PIM_cmd c, unsigned int v1, unsigned int v2,
00662                                 unsigned int v3, unsigned int v4,
00663                                 unsigned int v5, unsigned int v6)
00664 {
00665   asm volatile ("mr r3, %0\n" /* c */
00666                "mr r4, %1\n" /* v1 */
00667                "mr r5, %2\n" /* v2 */
00668                "mr r6, %3\n" /* v3 */
00669                "mr r7, %4\n" /* v4 */
00670                "mr r8, %5\n" /* v5 */
00671                "mr r9, %6\n" /* v6 */
00672                "li r0, %7\n" /* Set to syscall */
00673                "sc\n" /* make the "system call" */
00674                 :
00675                 : "r" (c), "r" (v1), "r" (v2), "r" (v3), "r" (v4), "r" (v5), "r" (v6), "K"(SS_PIM_WRITE_SPECIAL6)
00676                 : "r0", "r3", "r4", "r5", "r6", "r7", "r8", "r9");
00677 }
00678 
00679 _INLINE_ void PIM_writeSpecial7(PIM_cmd c, unsigned int v1, unsigned int v2,
00680                                 unsigned int v3, unsigned int v4, 
00681                                 unsigned int v5, unsigned int v6,
00682                                 unsigned int v7)
00683 {
00684   asm volatile ("mr r3, %0\n" /* c */
00685                "mr r4, %1\n" /* v1 */
00686                "mr r5, %2\n" /* v2 */
00687                "mr r6, %3\n" /* v3 */
00688                "mr r7, %4\n" /* v4 */
00689                "mr r8, %5\n" /* v5 */
00690                "mr r9, %6\n" /* v6 */
00691                "mr r10, %7\n" /* v7 */
00692                "li r0, %8\n" /* Set to syscall */
00693                "sc\n" /* make the "system call" */
00694                 :
00695                 : "r" (c), "r" (v1), "r" (v2), "r" (v3), "r" (v4), "r" (v5), "r" (v6), "r" (v7), "K"(SS_PIM_WRITE_SPECIAL7)
00696                 : "r0", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10");
00697 }
00698 
00699 _INLINE_ int PIM_rwSpecial3(PIM_cmd c, unsigned int v1, unsigned int v2,
00700                           unsigned int v3)
00701 {
00702   int result;
00703   asm volatile ("mr r3, %1\n" /* c */
00704                 "mr r4, %2\n" /* v1 */
00705                 "mr r5, %3\n" /* v2 */
00706                 "mr r6, %4\n" /* v3 */
00707                 "li r0, %5\n" /* Set to syscall */
00708                 "sc\n" /* make the "system call" */
00709                 "mr %0, r3\n" /* Collect results*/
00710                 : "=r" (result)
00711                 : "r" (c), "r" (v1), "r" (v2), "r" (v3), "K"(SS_PIM_WRITE_SPECIAL3)
00712                 : "r0", "r3", "r4", "r5", "r6", "memory");
00713   return result;
00714 }
00715 
00716 _INLINE_ int PIM_readSpecial(PIM_cmd c)
00717 {
00718   int result;
00719   ONE_ARG_SYSCALL(SS_PIM_READ_SPECIAL, c, result);
00720   return result;
00721 }
00722 
00723 _INLINE_ int PIM_readSpecial1(PIM_cmd c, unsigned int v)
00724 {
00725   int result;
00726   TWO_ARG_SYSCALL(SS_PIM_READ_SPECIAL1, c, v, result);
00727   return result;
00728 }
00729 
00730 _INLINE_ int PIM_readSpecial2(PIM_cmd c, unsigned int v1, unsigned int v2)
00731 {
00732   int result;
00733   asm volatile ("mr r3, %1\n" /* c */
00734                 "mr r4, %2\n" /* v1 */
00735                 "mr r5, %3\n" /* v2 */
00736                 "li r0, %4\n" /* Set to syscall */
00737                 "sc\n" /* make the "system call" */
00738                 "mr %0, r3\n" /* Collect results*/
00739                 : "=r" (result)
00740                 : "r" (c), "r" (v1), "r" (v2), "K"(SS_PIM_READ_SPECIAL2)
00741                 : "r0", "r3", "r4", "r5", "memory");
00742   return result;
00743 }
00744 
00745 _INLINE_ int PIM_readSpecial3(PIM_cmd c, unsigned int v1, unsigned int v2, 
00746                             unsigned int v3)
00747 {
00748   int result;
00749   asm volatile ("mr r3, %1\n" /* c */
00750                 "mr r4, %2\n" /* v1 */
00751                 "mr r5, %3\n" /* v2 */
00752                 "mr r6, %4\n" /* v3 */
00753                 "li r0, %5\n" /* Set to syscall */
00754                 "sc\n" /* make the "system call" */
00755                 "mr %0, r3\n" /* Collect results*/
00756                 : "=r" (result)
00757                 : "r" (c), "r" (v1), "r" (v2), "r" (v3), "K"(SS_PIM_READ_SPECIAL3)
00758                 : "r0", "r3", "r4", "r5", "r6", "memory");
00759   return result;
00760 }
00761 
00762 _INLINE_ int PIM_readSpecial4(PIM_cmd c, unsigned int v1, unsigned int v2, 
00763                             unsigned int v3, unsigned int v4)
00764 {
00765   int result;
00766   asm volatile ("mr r3, %1\n" /* c */
00767                 "mr r4, %2\n" /* v1 */
00768                 "mr r5, %3\n" /* v2 */
00769                 "mr r6, %4\n" /* v3 */
00770                 "mr r7, %5\n" /* v3 */
00771                 "li r0, %6\n" /* Set to syscall */
00772                 "sc\n" /* make the "system call" */
00773                 "mr %0, r3\n" /* Collect results*/
00774                 : "=r" (result)
00775                 : "r" (c), "r" (v1), "r" (v2), "r" (v3), "r" (v4), "K"(SS_PIM_READ_SPECIAL4)
00776                 : "r0", "r3", "r4", "r5", "r6", "r7", "memory");
00777   return result;
00778 }
00779 
00780 _INLINE_ int PIM_readSpecial1_2(PIM_cmd c, unsigned int v, unsigned int *o2)
00781 {
00782   int result1;
00783   int result2;
00784   asm volatile ("mr r3, %2\n" /* c */
00785                 "mr r4, %3\n" /* v */
00786                 "li r0, %4\n" /* Set to syscall */
00787                 "sc\n" /* make the "system call" */
00788                 "mr %0, r3\n" /* Collect results*/
00789                 "mr %1, r4\n" /* Collect results*/
00790                 : "=r" (result1), "=r" (result2)
00791                 : "r" (c), "r" (v), "K"(SS_PIM_READ_SPECIAL1_2)
00792                 : "r0", "r3", "r4", "memory");
00793   *o2 = result1;
00794   return result2;
00795 }
00796 
00797 _INLINE_ int PIM_readSpecial_2(PIM_cmd c, unsigned int *o2)
00798 {
00799   int result1;
00800   int result2;
00801   asm volatile ("mr r3, %2\n" /* c */
00802                 "li r0, %3\n" /* Set to syscall */
00803                 "sc\n" /* make the "system call" */
00804                 "mr %0, r3\n" /* Collect results*/
00805                 "mr %1, r4\n" /* Collect results*/
00806                 : "=r" (result1), "=r" (result2)
00807                 : "r" (c), "K"(SS_PIM_READ_SPECIAL_2)
00808                 : "r0", "r3", "r4", "memory");
00809   *o2 = result1;
00810   return result2;
00811 }
00812 
00813 _INLINE_ int PIM_readSpecial1_5(PIM_cmd c, unsigned int v, unsigned int *o2,
00814                               unsigned int *o3, unsigned int *o4,
00815                               unsigned int *o5)
00816 {
00817   int result1, result2, result3, result4, result5;
00818   asm volatile ("mr r3, %5\n" /* c */
00819                 "mr r4, %6\n" /* v */
00820                 "li r0, %7\n" /* Set to syscall */
00821                 "sc\n" /* make the "system call" */
00822                 "mr %0, r3\n" /* Collect results*/
00823                 "mr %1, r4\n" /* Collect results*/
00824                 "mr %2, r5\n" /* Collect results*/
00825                 "mr %3, r6\n" /* Collect results*/
00826                 "mr %4, r7\n" /* Collect results*/
00827                 : "=r" (result1), "=r" (result2), "=r" (result3), "=r" (result4), "=r" (result5)
00828                 : "r" (c), "r" (v), "K"(SS_PIM_READ_SPECIAL1_5)
00829                 : "r0", "r3", "r4", "r5", "r6", "r7", "memory");
00830   *o2 = result1;   *o3 = result2;  *o4 = result3;   *o5 = result4;
00831   return result5;
00832 }
00833 
00834 _INLINE_ void PIM_readSpecial1_6(PIM_cmd c, unsigned int v, unsigned int *o1,
00835                               unsigned int *o2, unsigned int *o3,
00836                                 unsigned int *o4, unsigned int *o5,
00837                                 unsigned *o6)
00838 {
00839   int result1, result2, result3, result4, result5, result6;
00840   asm volatile ("mr r3, %6\n" /* c */
00841                 "mr r4, %7\n" /* v */
00842                 "li r0, %8\n" /* Set to syscall */
00843                 "sc\n" /* make the "system call" */
00844                 "mr %0, r3\n" /* Collect results*/
00845                 "mr %1, r4\n" /* Collect results*/
00846                 "mr %2, r5\n" /* Collect results*/
00847                 "mr %3, r6\n" /* Collect results*/
00848                 "mr %4, r7\n" /* Collect results*/
00849                 "mr %5, r8\n" /* Collect results*/
00850                 : "=r" (result1), "=r" (result2), "=r" (result3), "=r" (result4), "=r" (result5), "=r" (result6)
00851                 : "r" (c), "r" (v), "K"(SS_PIM_READ_SPECIAL1_6)
00852                 : "r0", "r3", "r4", "r5", "r6", "r7", "r8", "memory");
00853   *o1 = result1;   *o2 = result2;  *o3 = result3;   *o4 = result4;
00854   *o5 = result5;   *o6 = result6;
00855 }
00856 
00857 _INLINE_ void PIM_readSpecial1_7(PIM_cmd c, unsigned int v, unsigned int *o1,
00858                               unsigned int *o2, unsigned int *o3,
00859                                 unsigned int *o4, unsigned int *o5,
00860                                  unsigned int *o6, unsigned int *o7)
00861 {
00862   int result1, result2, result3, result4, result5, result6, result7;
00863   asm volatile ("mr r3, %7\n" /* c */
00864                 "mr r4, %8\n" /* v */
00865                 "li r0, %9\n" /* Set to syscall */
00866                 "sc\n" /* make the "system call" */
00867                 "mr %0, r3\n" /* Collect results*/
00868                 "mr %1, r4\n" /* Collect results*/
00869                 "mr %2, r5\n" /* Collect results*/
00870                 "mr %3, r6\n" /* Collect results*/
00871                 "mr %4, r7\n" /* Collect results*/
00872                 "mr %5, r8\n" /* Collect results*/
00873                 "mr %6, r9\n" /* Collect results*/
00874                 : "=r" (result1), "=r" (result2), "=r" (result3), "=r" (result4), "=r" (result5), "=r" (result6), "=r" (result7)
00875                 : "r" (c), "r" (v), "K"(SS_PIM_READ_SPECIAL1_7)
00876                 : "r0", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "memory");
00877   *o1 = result1;   *o2 = result2;  *o3 = result3;   *o4 = result4;
00878   *o5 = result5;   *o6 = result6; *o7 = result7;
00879 }
00880 
00881 #if defined(__cplusplus)
00882 _INLINE_ void PIM_writeSpecial(PIM_cmd c, unsigned int v1, unsigned int v2) {
00883   PIM_writeSpecial2(c, v1, v2);
00884 }
00885 _INLINE_ void PIM_writeSpecial(PIM_cmd c, unsigned int v1, unsigned int v2,
00886                              unsigned int v3) {
00887   PIM_writeSpecial3(c, v1, v2, v3);
00888 }
00889 _INLINE_ void PIM_writeSpecial(PIM_cmd c, unsigned int v1, unsigned int v2,
00890                              unsigned int v3, unsigned int v4) {
00891   PIM_writeSpecial4(c, v1, v2, v3, v4);
00892 }
00893 _INLINE_ void PIM_writeSpecial(PIM_cmd c, unsigned int v1, unsigned int v2,
00894                              unsigned int v3, unsigned int v4,
00895                              unsigned int v5) {
00896   PIM_writeSpecial5(c, v1, v2, v3, v4, v5);
00897 }
00898 _INLINE_ int PIM_readSpecial(PIM_cmd c, unsigned int v) {
00899   return PIM_readSpecial1(c, v);
00900 }
00901 _INLINE_ int PIM_readSpecial(PIM_cmd c, unsigned int v1, unsigned int v2) {
00902   return PIM_readSpecial2(c, v1, v2);
00903 }
00904 _INLINE_ int PIM_readSpecial(PIM_cmd c, unsigned int v1, unsigned int v2,
00905                            unsigned int v3) {
00906   return PIM_readSpecial3(c, v1, v2, v3);
00907 }
00908 _INLINE_ int PIM_readSpecial(PIM_cmd c, unsigned int v1, unsigned int v2,
00909                            unsigned int v3, unsigned int v4) {
00910   return PIM_readSpecial4(c, v1, v2, v3, v4);
00911 }
00912 #endif
00913 
00914 //: Switch between either PIM_feb_readfe or PIM_feb_writeef depending on the :defaultFEB
00915 //
00916 // The idea is that this allows things like pthread_mutex_lock to be
00917 // implemented reliably regardless of simulator configuration changes,
00918 // while still using the FEB subsystem. Essentially, this is identical to
00919 // PIM_feb_writeef if :defaultFEB is 0, and is identical to PIM_feb_readfe
00920 // if :defaultFEB is 1
00921 _INLINE_ unsigned int PIM_feb_lock(unsigned int* a)
00922 {
00923     unsigned int result;
00924     ONE_ARG_SYSCALL(SS_PIM_LOCK, a, result);
00925     return result;
00926 }
00927 
00928 //: Switch between either PIM_feb_fill or PIM_feb_empty depending on the :defaultFEB
00929 //
00930 // The idea is that this allows things like pthread_mutex_unlock to be
00931 // implemented reliably regardless of simulator configuration changes,
00932 // while still using the FEB subsystem. Essentially, this is identical to
00933 // PIM_feb_empty if :defaultFEB is 0, and is identical to PIM_feb_fill
00934 // if :defaultFEB is 1
00935 _INLINE_ unsigned int PIM_feb_unlock(unsigned int* a)
00936 {
00937     unsigned int result;
00938     ONE_ARG_SYSCALL(SS_PIM_UNLOCK, a, result);
00939     return result;
00940 }
00941 
00942 //: Read if FEB is full, set FEB to "full"
00943 //
00944 // Read a word at a specified address if the Full/Empty Bit (FEB)
00945 // associated with that word is "full." After the read, keep the FEB
00946 // to "full"
00947 _INLINE_ unsigned int PIM_feb_readff(volatile unsigned int* a)
00948 {
00949   unsigned int result;
00950   ONE_ARG_SYSCALL(SS_PIM_READFF, a, result);
00951   return result;
00952 }
00953 _INLINE_ unsigned int PIM_feb_try_readff(volatile unsigned int* dest, const unsigned int *src)
00954 {
00955   unsigned int result;
00956   TWO_ARG_SYSCALL(SS_PIM_TRY_READFF, dest, src, result);
00957   return result;
00958 }
00959 
00960 //: Read if FEB is full, set FEB to "empty"
00961 //
00962 // Read a word at a specified address if the Full/Empty Bit (FEB)
00963 // associated with that word is "full." After the read, set the FEB
00964 // to "empty"
00965 _INLINE_ unsigned int PIM_feb_readfe(volatile unsigned int* a)
00966 {
00967   unsigned int result;
00968   ONE_ARG_SYSCALL(SS_PIM_READFE, a, result);
00969   return result;
00970 }
00971 _INLINE_ unsigned int PIM_feb_try_readfe(volatile unsigned int* dest, const unsigned int* src)
00972 {
00973     unsigned int result;
00974     TWO_ARG_SYSCALL(SS_PIM_TRY_READFE, dest, src, result);
00975     return result;
00976 }
00977 
00978 //: Atomically Increment integer at a given address
00979 //
00980 //!in: a: address of the integer to increment
00981 _INLINE_ int PIM_atomicIncrement(volatile unsigned int* a, unsigned int i)
00982 {
00983   int result;
00984 
00985   TWO_ARG_SYSCALL(SS_PIM_ATOMIC_INCREMENT, a, i, result);
00986 
00987   return result;
00988 }
00989 
00990 //: Write if FEB is empty, set FEB to "full"
00991 //
00992 // Write a word at the specified address if the FEB associated with
00993 // that word is "empty," After the write, set the FEB to "full"
00994 _INLINE_ void PIM_feb_writeef(volatile unsigned int* a, unsigned int v)
00995 {
00996     TWO_ARG_VOID_SYSCALL(SS_PIM_WRITEEF, a, v);
00997 }
00998 _INLINE_ unsigned int PIM_feb_try_writeef(volatile unsigned int* a, const unsigned int *v)
00999 {
01000     unsigned int result;
01001     TWO_ARG_SYSCALL(SS_PIM_TRY_WRITEEF, a, v, result);
01002     return result;
01003 }
01004 
01005 
01006 
01007 
01008 //: Set a Full/Empty bit to "full"
01009 //
01010 // Set the FEB associated with the given address to "full" - do not
01011 // change the data contents of the associated address.
01012 _INLINE_ void PIM_feb_fill(unsigned int* a) {
01013     ONE_ARG_VOID_SYSCALL(SS_PIM_FILL_FE, a);
01014 }
01015 
01016 //: Set a Full/Empty bit to "empty"
01017 //
01018 // Set the FEB associated with the given address to "empty" - do not
01019 // change the data contents of the associated address.
01020 _INLINE_ void PIM_feb_empty(unsigned int* a) {
01021     ONE_ARG_VOID_SYSCALL(SS_PIM_EMPTY_FE, a);
01022 }
01023 
01024 //: Set a Full/Empty bit to "empty"
01025 //
01026 // Set the FEB associated with the given address to "empty" - do not
01027 // change the data contents of the associated address.
01028 //
01029 // This is the same as PIM_feb_empty(), it is provided to remain
01030 // consistent with Cray terminology.
01031 _INLINE_ void PIM_feb_purge(unsigned int* a)
01032 {
01033   PIM_feb_empty(a);
01034 }
01035 
01036 //: Check the fullness of a FEB
01037 //
01038 // Check is the FEB assoicated with a specified memory address is set
01039 // to "full"(1) or "empty"(0).
01040 _INLINE_ int PIM_feb_is_full(unsigned int* a)
01041 {
01042   int result;
01043   ONE_ARG_SYSCALL(SS_PIM_IS_FE_FULL, a, result);
01044   return result;
01045 }
01046 
01047 //: Try to lock a FEB
01048 //
01049 // Attempt to move given FEB from empty to full. If it is already
01050 // full, returns 1, else returns 0.
01051 _INLINE_ int PIM_feb_tryef(unsigned int* a)
01052 {
01053   int result;
01054   ONE_ARG_SYSCALL(SS_PIM_TRYEF, a, result);
01055   return result;
01056 }
01057 
01058 #ifdef __cplusplus
01059 
01060 //: Read if FEB is full, set FEB to "full"
01061 //
01062 // Read a word at a specified address if the Full/Empty Bit (FEB)
01063 // associated with that word is "full." After the read, keep the FEB
01064 // to "full"
01065 //
01066 // This is a templatized version of PIM_feb_readff()
01067 template <class T>
01068 _INLINE_ T PIM_readff(volatile T* a) {
01069   return (T)PIM_feb_readff((volatile unsigned int*)a);
01070 }
01071 
01072 //: Read if FEB is full, set FEB to "empty"
01073 //
01074 // Read a word at a specified address if the Full/Empty Bit (FEB)
01075 // associated with that word is "full." After the read, set the FEB
01076 // to "empty"
01077 //
01078 // This is a templatized version of PIM_feb_readfe()
01079 template <class T>
01080 _INLINE_ T PIM_readfe(volatile T* a) {
01081   return (T)PIM_feb_readfe((volatile unsigned int*)a);
01082 }
01083 
01084 //: Write if FEB is empty, set FEB to "full"
01085 //
01086 // Write a word at the specified address if the FEB associated with
01087 // that word is "empty," After the write, set the FEB to "full"
01088 //
01089 // This is a templatized version of PIM_feb_writeef()
01090 template <class T>
01091 _INLINE_ void PIM_writeef(volatile T* a, T v) {
01092   PIM_feb_writeef((volatile unsigned int*)a, (unsigned int)v);
01093 }
01094 
01095 //: Set a Full/Empty bit to "full"
01096 //
01097 // Set the FEB associated with the given address to "full" - do not
01098 // change the data contents of the associated address.
01099 //
01100 // This is a templatized version of PIM_feb_fill()
01101 template <class T>
01102 _INLINE_ void PIM_fill(T* a) {
01103   PIM_feb_fill((unsigned int*)a);
01104 }
01105 
01106 //: Set a Full/Empty bit to "empty"
01107 //
01108 // Set the FEB associated with the given address to "empty" - do not
01109 // change the data contents of the associated address.
01110 //
01111 // This is a templatized version of PIM_feb_empty()
01112 template <class T>
01113 _INLINE_ void PIM_empty(T* a) {
01114   PIM_feb_empty((unsigned int*) a);
01115 }
01116 
01117 //: Set a Full/Empty bit to "empty"
01118 //
01119 // Set the FEB associated with the given address to "empty" - do not
01120 // change the data contents of the associated address.
01121 //
01122 // This is the same as PIM_empty(), it is provided to remain
01123 // consistent with Cray terminology.
01124 template <class T>
01125 _INLINE_ int PIM_purge(T* a) {
01126   return PIM_feb_purge((unsigned int*)a);
01127 }
01128 
01129 //: Check the fullness of a FEB
01130 //
01131 // Check is the FEB assoicated with a specified memory address is set
01132 // to "full"(1) or "empty"(0).
01133 //
01134 // This is a templatized version of PIM_feb_empty()
01135 template <class T>
01136 _INLINE_ int PIM_is_full(T* a) {
01137   return PIM_feb_is_full((unsigned int*)a);
01138 }
01139 #endif
01140 
01141 
01142 //:Reset performance counters
01143 //
01144 // Resets counts of instructions, cycles, and migrations.
01145 _INLINE_ void PIM_resetCounters(void)
01146 {
01147     VOID_SYSCALL(SS_PIM_RESET);
01148 }
01149 
01150 //:Terminate a PIM thread
01151 //
01152 // Wrapper around the PIM system call.
01153 _INLINE_ void PIM_threadExit(void) __attribute__((noreturn));
01154 _INLINE_ void PIM_threadExit(void)
01155 {
01156     VOID_SYSCALL(SS_PIM_EXIT);
01157 /* NOTE: this function is marked (noreturn), and the compiler ordinarily
01158  * complains that this function falls off the bottom. BUT, to suppress this
01159  * warning, we've added this infinite-loop to the end of the function. The
01160  * compiler is smart enough to realize that this prevents the function from
01161  * ever returning (for a minimum of instructions wasted), but unfortunately
01162  * forces the compiler to add dead code to the function. Sorry :-( */
01163   for (;;) continue;
01164 }
01165 
01166 /* this makes sure the stack is freed */
01167 _INLINE_ void PIM_threadExitFree(void) __attribute__((__noreturn__));
01168 _INLINE_ void PIM_threadExitFree(void)
01169 {
01170     VOID_SYSCALL(SS_PIM_EXIT_FREE);
01171 /* NOTE: this function is marked (noreturn), and the compiler ordinarily
01172  * complains that this function falls off the bottom. BUT, to suppress this
01173  * warning, we've added this infinite-loop to the end of the function. The
01174  * compiler is smart enough to realize that this prevents the function from
01175  * ever returning (for a minimum of instructions wasted), but unfortunately
01176  * forces the compiler to add dead code to the function. Sorry :-( */
01177   for (;;) continue;
01178 }
01179 
01180 #endif

Generated on Fri Oct 22 2010 11:02:24 for SST by  doxygen 1.7.1