RedShedThreadContext.h from redshed at Krugle
Show RedShedThreadContext.h syntax highlighted
/****************************************************************************************
RedShedThreadContext.h $Revision: 1.2 $
<http://rentzsch.com/redshedthreads>
Copyright © 1998-2002 Red Shed Software. All rights reserved.
by Jonathan 'Wolf' Rentzsch (jon at redshed dot net)
************************************************************************************/
#ifndef _RedShedThreadContext_
#define _RedShedThreadContext_
/**************************
*
* Types
*
**************************/
#pragma mark (Types)
typedef struct RedShedThreadContext RedShedThreadContext;
typedef long RedShedThreadContextID;
typedef pascal long (*RedShedThreadContextSaver)( RedShedThreadContext *context );
typedef pascal void (*RedShedThreadContextResumer)( RedShedThreadContext *context );
typedef struct AltiVecReg { // A 128 (32 * 4) bit value.
long a;
long b;
long c;
long d;
} AltiVecReg;
// It's probably not a good idea to modify the following structures.
#pragma mark RedShedThreadContext
struct RedShedThreadContext { // Offset Size Total
RedShedThreadContextID id; // 0 4 4
RedShedThreadContextSaver saver; // 4 4 8
RedShedThreadContextResumer resumer; // 8 4 12
// ...Model-specific registers follow...
};
#pragma mark RedShedThreadContext68K
typedef struct RedShedThreadContext68K { // Offset Size Total
RedShedThreadContextID id; // 0 4 4
RedShedThreadContextSaver saver; // 4 4 8
RedShedThreadContextResumer resumer; // 8 4 12
long pc; // 12 4 16
long d3; // 16 4 20
long d4; // 20 4 24
long d5; // 24 4 28
long d6; // 28 4 32
long d7; // 32 4 36
long a1; // 36 4 40
long a2; // 40 4 44
long a3; // 44 4 48
long a4; // 48 4 52
long a5; // 52 4 56
long a6; // 56 4 60
long sp; // 60 4 64
} RedShedThreadContext68K;
#pragma mark RedShedThreadContext68881
typedef struct RedShedThreadContext68881 { // Offset Size Total
RedShedThreadContextID id; // 0 4 4
RedShedThreadContextSaver saver; // 4 4 8
RedShedThreadContextResumer resumer; // 8 4 12
long pc; // 12 4 16
long d3; // 16 4 20
long d4; // 20 4 24
long d5; // 24 4 28
long d6; // 28 4 32
long d7; // 32 4 36
long a1; // 36 4 40
long a2; // 40 4 44
long a3; // 44 4 48
long a4; // 48 4 52
long a5; // 52 4 56
long a6; // 56 4 60
long sp; // 60 4 64
long double fp4; // 64 12 76
long double fp5; // 76 12 88
long double fp6; // 88 12 100
long double fp7; // 100 12 112
} RedShedThreadContext68881;
#pragma mark RedShedThreadContextPPC
typedef struct RedShedThreadContextPPC { // Offset Size Total
RedShedThreadContextID id; // 0 4 4
RedShedThreadContextSaver saver; // 4 4 8
RedShedThreadContextResumer resumer; // 8 4 12
long pc; // 12 4 16
long cr; // 16 4 20
long sp; // 20 4 24
long toc; // 24 4 28
long r13; // 28 4 32
long r14; // 32 4 36
long r15; // 36 4 40
long r16; // 40 4 44
long r17; // 44 4 48
long r18; // 48 4 52
long r19; // 52 4 56
long r20; // 56 4 60
long r21; // 60 4 64
long r22; // 64 4 68
long r23; // 68 4 72
long r24; // 72 4 76
long r25; // 76 4 80
long r26; // 80 4 84
long r27; // 84 4 88
long r28; // 88 4 92
long r29; // 92 4 96
long r30; // 96 4 100
long r31; // 100 4 104
double fp14; // 104 8 112 // should be 8 byte aligned
double fp15; // 112 8 120
double fp16; // 120 8 128
double fp17; // 128 8 136
double fp18; // 136 8 144
double fp19; // 144 8 152
double fp20; // 152 8 160
double fp21; // 160 8 168
double fp22; // 168 8 176
double fp23; // 176 8 184
double fp24; // 184 8 192
double fp25; // 192 8 200
double fp26; // 200 8 208
double fp27; // 208 8 216
double fp28; // 216 8 224
double fp29; // 224 8 232
double fp30; // 232 8 240
double fp31; // 240 8 248
double fpscr; // 248 8 256
} RedShedThreadContextPPC;
#pragma mark RedShedThreadContextPPCFP
typedef struct RedShedThreadContextPPCFP { // Offset Size Total
RedShedThreadContextID id; // 0 4 4
RedShedThreadContextSaver saver; // 4 4 8
RedShedThreadContextResumer resumer; // 8 4 12
long pc; // 12 4 16
long cr; // 16 4 20
long sp; // 20 4 24
long toc; // 24 4 28
long r13; // 28 4 32
long r14; // 32 4 36
long r15; // 36 4 40
long r16; // 40 4 44
long r17; // 44 4 48
long r18; // 48 4 52
long r19; // 52 4 56
long r20; // 56 4 60
long r21; // 60 4 64
long r22; // 64 4 68
long r23; // 68 4 72
long r24; // 72 4 76
long r25; // 76 4 80
long r26; // 80 4 84
long r27; // 84 4 88
long r28; // 88 4 92
long r29; // 92 4 96
long r30; // 96 4 100
long r31; // 100 4 104
double fp0; // 104 8 112 // should be 8 byte aligned
double fp1; // 112 8 120
double fp2; // 120 8 128
double fp3; // 128 8 136
double fp4; // 136 8 144
double fp5; // 144 8 152
double fp6; // 152 8 160
double fp7; // 160 8 168
double fp8; // 168 8 176
double fp9; // 176 8 184
double fp10; // 184 8 192
double fp11; // 192 8 200
double fp12; // 200 8 208
double fp13; // 208 8 216
double fp14; // 216 8 224
double fp15; // 224 8 232
double fp16; // 232 8 240
double fp17; // 240 8 248
double fp18; // 248 8 256
double fp19; // 256 8 264
double fp20; // 264 8 272
double fp21; // 272 8 280
double fp22; // 280 8 288
double fp23; // 288 8 296
double fp24; // 296 8 304
double fp25; // 304 8 312
double fp26; // 312 8 320
double fp27; // 320 8 328
double fp28; // 328 8 336
double fp29; // 336 8 344
double fp30; // 344 8 352
double fp31; // 352 8 360
double fpscr; // 360 8 368
} RedShedThreadContextPPCFP;
#pragma mark RedShedThreadContextAltiVec
typedef struct RedShedThreadContextAltiVec { // Offset Size Total
RedShedThreadContextID id; // 0 4 4
RedShedThreadContextSaver saver; // 4 4 8
RedShedThreadContextResumer resumer; // 8 4 12
long pc; // 12 4 16
long cr; // 16 4 20
long sp; // 20 4 24
long toc; // 24 4 28
long r13; // 28 4 32
long r14; // 32 4 36
long r15; // 36 4 40
long r16; // 40 4 44
long r17; // 44 4 48
long r18; // 48 4 52
long r19; // 52 4 56
long r20; // 56 4 60
long r21; // 60 4 64
long r22; // 64 4 68
long r23; // 68 4 72
long r24; // 72 4 76
long r25; // 76 4 80
long r26; // 80 4 84
long r27; // 84 4 88
long r28; // 88 4 92
long r29; // 92 4 96
long r30; // 96 4 100
long r31; // 100 4 104
double fp14; // 104 8 112 // should be 8 byte aligned
double fp15; // 112 8 120
double fp16; // 120 8 128
double fp17; // 128 8 136
double fp18; // 136 8 144
double fp19; // 144 8 152
double fp20; // 152 8 160
double fp21; // 160 8 168
double fp22; // 168 8 176
double fp23; // 176 8 184
double fp24; // 184 8 192
double fp25; // 192 8 200
double fp26; // 200 8 208
double fp27; // 208 8 216
double fp28; // 216 8 224
double fp29; // 224 8 232
double fp30; // 232 8 240
double fp31; // 240 8 248
double fpscr; // 248 8 256
AltiVecReg vr0; // 256 16 272 // must be 16 byte aligned
AltiVecReg vr1; // 272 16 288
AltiVecReg vr2; // 288 16 304
AltiVecReg vr3; // 304 16 320
AltiVecReg vr4; // 320 16 336
AltiVecReg vr5; // 336 16 352
AltiVecReg vr6; // 352 16 368
AltiVecReg vr7; // 368 16 384
AltiVecReg vr8; // 384 16 400
AltiVecReg vr9; // 400 16 416
AltiVecReg vr10; // 416 16 432
AltiVecReg vr11; // 432 16 448
AltiVecReg vr12; // 448 16 464
AltiVecReg vr13; // 464 16 480
AltiVecReg vr14; // 480 16 496
AltiVecReg vr15; // 496 16 512
AltiVecReg vr16; // 512 16 528
AltiVecReg vr17; // 528 16 544
AltiVecReg vr18; // 544 16 560
AltiVecReg vr19; // 560 16 576
AltiVecReg vr20; // 576 16 592
AltiVecReg vr21; // 592 16 608
AltiVecReg vr22; // 608 16 624
AltiVecReg vr23; // 624 16 640
AltiVecReg vr24; // 640 16 656
AltiVecReg vr25; // 656 16 672
AltiVecReg vr26; // 672 16 688
AltiVecReg vr27; // 688 16 704
AltiVecReg vr28; // 704 16 720
AltiVecReg vr29; // 720 16 736
AltiVecReg vr30; // 736 16 752
AltiVecReg vr31; // 752 16 768
AltiVecReg vscr; // 768 16 784
long vrsave; // 784 4 788
} RedShedThreadContextAltiVec;
#pragma mark RedShedThreadContextAltiVecFP
typedef struct RedShedThreadContextAltiVecFP {
// Offset Size Total
RedShedThreadContextID id; // 0 4 4
RedShedThreadContextSaver saver; // 4 4 8
RedShedThreadContextResumer resumer; // 8 4 12
long pc; // 12 4 16
long cr; // 16 4 20
long sp; // 20 4 24
long toc; // 24 4 28
long r13; // 28 4 32
long r14; // 32 4 36
long r15; // 36 4 40
long r16; // 40 4 44
long r17; // 44 4 48
long r18; // 48 4 52
long r19; // 52 4 56
long r20; // 56 4 60
long r21; // 60 4 64
long r22; // 64 4 68
long r23; // 68 4 72
long r24; // 72 4 76
long r25; // 76 4 80
long r26; // 80 4 84
long r27; // 84 4 88
long r28; // 88 4 92
long r29; // 92 4 96
long r30; // 96 4 100
long r31; // 100 4 104
double fp0; // 104 8 112 // should be 8 byte aligned
double fp1; // 112 8 120
double fp2; // 120 8 128
double fp3; // 128 8 136
double fp4; // 136 8 144
double fp5; // 144 8 152
double fp6; // 152 8 160
double fp7; // 160 8 168
double fp8; // 168 8 176
double fp9; // 176 8 184
double fp10; // 184 8 192
double fp11; // 192 8 200
double fp12; // 200 8 208
double fp13; // 208 8 216
double fp14; // 216 8 224
double fp15; // 224 8 232
double fp16; // 232 8 240
double fp17; // 240 8 248
double fp18; // 248 8 256
double fp19; // 256 8 264
double fp20; // 264 8 272
double fp21; // 272 8 280
double fp22; // 280 8 288
double fp23; // 288 8 296
double fp24; // 296 8 304
double fp25; // 304 8 312
double fp26; // 312 8 320
double fp27; // 320 8 328
double fp28; // 328 8 336
double fp29; // 336 8 344
double fp30; // 344 8 352
double fp31; // 352 8 360
double fpscr; // 360 8 368
AltiVecReg vr0; // 368 16 384 // must be 16 byte aligned
AltiVecReg vr1; // 384 16 400
AltiVecReg vr2; // 400 16 416
AltiVecReg vr3; // 416 16 432
AltiVecReg vr4; // 432 16 448
AltiVecReg vr5; // 448 16 464
AltiVecReg vr6; // 464 16 480
AltiVecReg vr7; // 480 16 496
AltiVecReg vr8; // 496 16 512
AltiVecReg vr9; // 512 16 528
AltiVecReg vr10; // 528 16 544
AltiVecReg vr11; // 544 16 560
AltiVecReg vr12; // 560 16 576
AltiVecReg vr13; // 576 16 592
AltiVecReg vr14; // 592 16 608
AltiVecReg vr15; // 608 16 624
AltiVecReg vr16; // 624 16 640
AltiVecReg vr17; // 640 16 656
AltiVecReg vr18; // 656 16 672
AltiVecReg vr19; // 672 16 688
AltiVecReg vr20; // 688 16 704
AltiVecReg vr21; // 704 16 720
AltiVecReg vr22; // 720 16 736
AltiVecReg vr23; // 736 16 752
AltiVecReg vr24; // 752 16 768
AltiVecReg vr25; // 768 16 784
AltiVecReg vr26; // 784 16 800
AltiVecReg vr27; // 800 16 816
AltiVecReg vr28; // 816 16 832
AltiVecReg vr29; // 832 16 848
AltiVecReg vr30; // 848 16 864
AltiVecReg vr31; // 864 16 880
AltiVecReg vscr; // 880 16 896
long vrsave; // 896 4 900
} RedShedThreadContextAltiVecFP;
#pragma mark RedShedThreadContextMax
#if powerc
#if __VEC__
typedef RedShedThreadContextAltiVecFP RedShedThreadContextMax;
#else
typedef RedShedThreadContextPPCFP RedShedThreadContextMax;
#endif
#else
#if __option(code68881)
typedef RedShedThreadContext68881 RedShedThreadContextMax;
#else
typedef RedShedThreadContext68K RedShedThreadContextMax;
#endif
#endif
#pragma mark ValidRedShedThreadContextCode
typedef enum {
kRedShedThreadContextValid = 0,
kRedShedThreadContextNil = 1,
kRedShedThreadContextNotAligned = 2,
kRedShedThreadContextInvalidID = 3,
kRedShedThreadContextInvalidSaver = 4,
kRedShedThreadContextInvalidResumer = 5,
kRedShedThreadContextWrongSize = 6,
kRedShedThreadContextStackIsNil = 7,
kRedShedThreadContextStackNotAligned = 8
} ValidRedShedThreadContextCode;
/**************************
*
* Constants
*
**************************/
#pragma mark -
#pragma mark (Constants)
#define kRedShedThreadContext68K '68K '
#define kRedShedThreadContext68881 '6881'
#define kRedShedThreadContextPPC 'PPC '
#define kRedShedThreadContextPPCFP 'PPCf'
#define kRedShedThreadContextAltiVec 'AVec'
#define kRedShedThreadContextAltiVecFP 'AVfp'
#if powerc
#define kRedShedThreadContextStd kRedShedThreadContextPPC
#if __VEC__
#define kRedShedThreadContextAlignment 16
#define kRedShedThreadStackAlignment 8
#else
#define kRedShedThreadContextAlignment 8
#define kRedShedThreadStackAlignment 8
#endif
#else
#define kRedShedThreadContextStd kRedShedThreadContext68K
#if __option(code68881)
#define kRedShedThreadContextAlignment 4
#define kRedShedThreadStackAlignment 2
#else
#define kRedShedThreadContextAlignment 4
#define kRedShedThreadStackAlignment 2
#endif
#endif
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
/**************************
*
* Interfaces
*
**************************/
#pragma mark -
#pragma mark (Functions)
/****************************************************************************************
Commenter Date Comment
--------- ----------------- -----------------------------------------------------
wolf Tue, Feb 16, 1999 Created.
wolf Thu, Aug 26, 1999 Err. It seems if a compiler can generate AltiVec
code, it will define __ALTIVEC_ whether or not it is
actually generating AltiVec code. The way to tell if
the compiler is currently generating AltiVec code
is to test for __VEC__.
wolf Sat, Aug 5, 2000 Version 2. Rewrote, now takes a
RedShedThreadContextID instead of a
RedShedThreadContextFlags.
When dynamically allocating memory for a RedShedThreadContext, call this function
to determine the necessary size.
************************************************************************************/
extern
pascal
unsigned long
GetRedShedThreadContextSize(
RedShedThreadContextID id );
/****************************************************************************************
Commenter Date Comment
--------- ----------------- -----------------------------------------------------
wolf Sat, Aug 5, 2000 Created for Version 2.
************************************************************************************/
extern
pascal
void
InitRedShedThreadContext(
RedShedThreadContext *context,
RedShedThreadContextID id );
/****************************************************************************************
Commenter Date Comment
--------- ----------------- -----------------------------------------------------
wolf Mon, Jun 1, 1998 Created.
wolf Thu, Nov 19, 1998 Rolled in PowerPC code.
wolf Tue, Feb 16, 1999 In preparing for AltiVec, I rewrote the code
to use the off( FIELD ) macro instead of hard-coded
offsets.
wolf Thu, Aug 26, 1999 Rewrote, throwing out all optimizations.
However, the code is smaller, easier to understand
and I added AltiVec support.
Once I'm sure it all works, I'll optimize it again.
wolf Sat, Aug 5, 2000 Version 2. Rewrote.
Saves the state of the caller into the structure pointed to by context.
Returns true after saving the state, false after reloading the context via
ResumeRedShedThreadContext().
************************************************************************************/
extern
pascal
long
SaveRedShedThreadContext(
RedShedThreadContext *context );
/****************************************************************************************
Commenter Date Comment
--------- ----------------- -----------------------------------------------------
wolf Mon, Jun 1, 1998 Created.
wolf Thu, Nov 19, 1998 Rolled in PowerPC code.
wolf Tue, Feb 16, 1999 In preparing for AltiVec, I rewrote the code
to use the off( FIELD ) macro instead of hard-coded
offsets.
wolf Thu, Aug 26, 1999 Rewrote, throwing out all optimizations.
However, the code is smaller, easier to understand
and I added AltiVec support.
Once I'm sure it all works, I'll optimize it again.
wolf Sat, Aug 5, 2000 Version 2. Rewrote.
Restores the context previously saved with SaveRedShedThreadContext().
************************************************************************************/
extern
pascal
void
ResumeRedShedThreadContext(
RedShedThreadContext *context );
/****************************************************************************************
Commenter Date Comment
--------- ----------------- -----------------------------------------------------
wolf Mon, Jan 3, 2000 Created.
wolf Wed, Apr 5, 2000 Now uses cookieRegister instead of lastDataRegister.
wolf Sat, Aug 5, 2000 Version 2. Rewrote.
************************************************************************************/
extern
pascal
void
SetRedShedThreadContextStack(
RedShedThreadContext *context,
void *stack,
long cookie );
/****************************************************************************************
Commenter Date Comment
--------- ----------------- -----------------------------------------------------
wolf Thu, Sep 30, 1999 Created.
wolf Wed, Apr 5, 2000 Now uses cookieRegister instead of lastDataRegister.
wolf Sat, Aug 5, 2000 Version 2, now uses the newly private
cookieRegister68K and cookieRegisterPPC.
************************************************************************************/
extern
pascal
long
GetRedShedThreadContextCookie();
/****************************************************************************************
Commenter Date Comment
--------- ----------------- -----------------------------------------------------
wolf Sat, Aug 5, 2000 Created for Version 2.
************************************************************************************/
extern
Boolean
IsValidRedShedThreadContextID(
RedShedThreadContextID id );
/****************************************************************************************
Commenter Date Comment
--------- ----------------- -----------------------------------------------------
wolf Sat, Aug 5, 2000 Created for Version 2.
************************************************************************************/
extern
ValidRedShedThreadContextCode
IsValidRedShedThreadContext(
RedShedThreadContext *context,
unsigned long size );
// The following macros are handy if you're using requirements...
#define RequireRedShedThreadContextID( ID ) \
Require( IsValidRedShedThreadContextID( ID ) )
#define RequireRedShedThreadContext( CONTEXT ) \
RequireEqual( IsValidRedShedThreadContext( CONTEXT, 0 ), kRedShedThreadContextValid )
#ifdef __cplusplus
}
#endif
#endif // _RedShedThreadContext_
See more files for this project here