summaryrefslogtreecommitdiff
path: root/ext/systemc/src/sysc/qt/md/ksr1.h
diff options
context:
space:
mode:
Diffstat (limited to 'ext/systemc/src/sysc/qt/md/ksr1.h')
-rw-r--r--ext/systemc/src/sysc/qt/md/ksr1.h164
1 files changed, 164 insertions, 0 deletions
diff --git a/ext/systemc/src/sysc/qt/md/ksr1.h b/ext/systemc/src/sysc/qt/md/ksr1.h
new file mode 100644
index 000000000..b3877505d
--- /dev/null
+++ b/ext/systemc/src/sysc/qt/md/ksr1.h
@@ -0,0 +1,164 @@
+/*
+ * QuickThreads -- Threads-building toolkit.
+ * Copyright (c) 1993 by David Keppel
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation for any purpose and without fee is hereby
+ * granted, provided that the above copyright notice and this notice
+ * appear in all copies. This software is provided as a
+ * proof-of-concept and for demonstration purposes; there is no
+ * representation about the suitability of this software for any
+ * purpose.
+ */
+
+#ifndef QUICKTHREADS_KSR1_H
+#define QUICKTHREADS_KSR1_H
+
+/*
+ Stack layout:
+
+ Registers are saved in strictly low to high order, FPU regs first
+ (only if qt_block is called), CEU regs second, IPU regs next, with no
+ padding between the groups.
+
+ Callee-save: f16..f63; c15..c30; i12..i30.
+ Args passed in i2..i5.
+
+ Note: c31 is a private data pointer. It is not changed on thread
+ swaps with the assumption that it represents per-processor rather
+ than per-thread state.
+
+ Note: i31 is an instruction count register that is updated by the
+ context switch routines. Like c31, it is not changed on context
+ switches.
+
+ This is what we want on startup:
+
+
+ +------ <-- BOS: Bottom of stack (grows down)
+ | 80 (128 - 48) bytes of padding to a 128-byte boundary
+ +---
+ | only
+ | userf
+ | t
+ | u
+ | qt_start$TXT
+ | (empty) <-- qt.sp
+ +------ <-- (BOS - 128)
+
+ This is why we want this on startup:
+
+ A thread begins running when the restore procedure switches thread stacks
+ and pops a return address off of the top of the new stack (see below
+ for the reason why we explicitly store qt_start$TXT). The
+ block procedure pushes two jump addresses on a thread's stack before
+ it switches stacks. The first is the return address for the block
+ procedure, and the second is a restore address. The return address
+ is used to jump back to the thread that has been switched to; the
+ restore address is a jump within the block code to restore the registers.
+ Normally, this is just a jump to the next address. However, on thread
+ startup, this is a jump to qt_start$TXT. (The block procedure stores
+ the restore address at an offset of 8 bytes from the top of the stack,
+ which is also the offset at which qt_start$TXT is stored on the stacks
+ of new threads. Hence, when the block procedure switches to a new
+ thread stack, it will initially jump to qt_start$TXT; thereafter,
+ it jumps to the restore code.)
+
+ qt_start$TXT, after it has read the initial data on the new thread's
+ stack and placed it in registers, pops the initial stack frame
+ and gives the thread the entire stack to use for execution.
+
+ The KSR runtime system has an unusual treatment of pointers to
+ functions. From C, taking the `name' of a function yields a
+ pointer to a _constant block_ and *not* the address of the
+ function. The zero'th entry in the constant block is a pointer to
+ the function.
+
+ We have to be careful: the restore procedure expects a return
+ address on the top of the stack (pointed to by qt.sp). This is not
+ a problem when restoring a thread that has run before, since the
+ block routine would have stored the return address on top of the
+ stack. However, when ``faking up'' a thread start (bootstrapping a
+ thread stack frame), the top of the stack needs to contain a
+ pointer to the code that will start the thread running.
+
+ The pointer to the startup code is *not* `qt_start'. It is the
+ word *pointed to* by `qt_start'. Thus, we dereference `qt_start',
+ see QUICKTHREADS_ARGS_MD below.
+
+ On varargs startup (still unimplemented):
+
+ | padding to 128 byte boundary
+ | varargs <-- padded to a 128-byte-boundary
+ +---
+ | caller's frame, 16 bytes
+ | 80 bytes of padding (frame padded to a 128-byte boundary)
+ +---
+ | cleanup
+ | vuserf
+ | startup
+ | t
+ +---
+ | qt_start <-- qt.sp
+ +---
+
+ Of a suspended thread:
+
+ +---
+ | caller's frame, 16 bytes
+ | fpu registers 47 regs * 8 bytes/reg 376 bytes
+ | ceu registers 16 regs * 8 bytes/reg 128 bytes
+ | ipu registers 19 regs * 8 bytes/reg 152 bytes
+ | :
+ | 80 bytes of padding
+ | :
+ | qt_restore <-- qt.sp
+ +---
+
+ */
+
+
+#define QUICKTHREADS_STKALIGN 128
+#define QUICKTHREADS_GROW_DOWN
+typedef unsigned long qt_word_t;
+
+#define QUICKTHREADS_STKBASE QUICKTHREADS_STKALIGN
+#define QUICKTHREADS_VSTKBASE QUICKTHREADS_STKBASE
+
+extern void qt_start(void);
+/*
+ * See the discussion above for what indexing into a procedure ptr
+ * does for us (it's lovely, though, isn't it?).
+ *
+ * This assumes that the address of a procedure's code is the
+ * first word in a procedure's constant block. That's how the manual
+ * says it will be arranged.
+ */
+#define QUICKTHREADS_ARGS_MD(sp) (QUICKTHREADS_SPUT (sp, 1, ((qt_word_t *)qt_start)[0]))
+
+/*
+ * The *index* (positive offset) of where to put each value.
+ * See the picture of the stack above that explains the offsets.
+ */
+#define QUICKTHREADS_ONLY_INDEX (5)
+#define QUICKTHREADS_USER_INDEX (4)
+#define QUICKTHREADS_ARGT_INDEX (3)
+#define QUICKTHREADS_ARGU_INDEX (2)
+
+#define QUICKTHREADS_VARGS_DEFAULT
+#define QUICKTHREADS_VARGS(sp, nb, vargs, pt, startup, vuserf, cleanup) \
+ (qt_vargs (sp, nbytes, &vargs, pt, startup, vuserf, cleanup))
+
+
+#define QUICKTHREADS_VARGS_MD0(sp, vabytes) \
+ ((qt_t *)(((char *)(sp)) - 4*8 - QUICKTHREADS_STKROUNDUP(vabytes)))
+
+extern void qt_vstart(void);
+#define QUICKTHREADS_VARGS_MD1(sp) (QUICKTHREADS_SPUT (sp, 0, ((qt_word_t *)qt_vstart)[0]))
+
+#define QUICKTHREADS_VCLEANUP_INDEX (4)
+#define QUICKTHREADS_VUSERF_INDEX (3)
+#define QUICKTHREADS_VSTARTUP_INDEX (2)
+#define QUICKTHREADS_VARGT_INDEX (1)
+
+#endif /* def QUICKTHREADS_KSR1_H */