i386.h revision 12027
18471SGiacomo.Gabrielli@arm.com/*
28471SGiacomo.Gabrielli@arm.com * QuickThreads -- Threads-building toolkit.
38471SGiacomo.Gabrielli@arm.com * Copyright (c) 1993 by David Keppel
48471SGiacomo.Gabrielli@arm.com *
58471SGiacomo.Gabrielli@arm.com * Permission to use, copy, modify and distribute this software and
68471SGiacomo.Gabrielli@arm.com * its documentation for any purpose and without fee is hereby
78471SGiacomo.Gabrielli@arm.com * granted, provided that the above copyright notice and this notice
88471SGiacomo.Gabrielli@arm.com * appear in all copies.  This software is provided as a
98471SGiacomo.Gabrielli@arm.com * proof-of-concept and for demonstration purposes; there is no
108471SGiacomo.Gabrielli@arm.com * representation about the suitability of this software for any
118471SGiacomo.Gabrielli@arm.com * purpose.
128471SGiacomo.Gabrielli@arm.com */
138471SGiacomo.Gabrielli@arm.com
148471SGiacomo.Gabrielli@arm.com#ifndef QUICKTHREADS_386_H
158471SGiacomo.Gabrielli@arm.com#define QUICKTHREADS_386_H
168471SGiacomo.Gabrielli@arm.com
178471SGiacomo.Gabrielli@arm.comtypedef unsigned long qt_word_t;
188471SGiacomo.Gabrielli@arm.com
198471SGiacomo.Gabrielli@arm.com/* Thread's initial stack layout on the i386:
208471SGiacomo.Gabrielli@arm.com
218471SGiacomo.Gabrielli@arm.com   non-varargs:
228471SGiacomo.Gabrielli@arm.com
238471SGiacomo.Gabrielli@arm.com   +---
248471SGiacomo.Gabrielli@arm.com   | arg[2]	=== `userf' on startup
258471SGiacomo.Gabrielli@arm.com   | arg[1]	=== `pt' on startup
268471SGiacomo.Gabrielli@arm.com   | arg[0]	=== `pu' on startup
278471SGiacomo.Gabrielli@arm.com   +---
288471SGiacomo.Gabrielli@arm.com   | ret pc === qt_error
298471SGiacomo.Gabrielli@arm.com   +---
308471SGiacomo.Gabrielli@arm.com   | ret pc	=== `only' on startup
318471SGiacomo.Gabrielli@arm.com   +---
328471SGiacomo.Gabrielli@arm.com   | %ebp
338471SGiacomo.Gabrielli@arm.com   | %esi
348471SGiacomo.Gabrielli@arm.com   | %edi
358471SGiacomo.Gabrielli@arm.com   | %ebx				<--- qt_t.sp
368471SGiacomo.Gabrielli@arm.com   +---
378471SGiacomo.Gabrielli@arm.com
388471SGiacomo.Gabrielli@arm.com   When a non-varargs thread is started, it ``returns'' directly to
398471SGiacomo.Gabrielli@arm.com   the client's `only' function.
408471SGiacomo.Gabrielli@arm.com
418471SGiacomo.Gabrielli@arm.com   varargs:
428471SGiacomo.Gabrielli@arm.com
438471SGiacomo.Gabrielli@arm.com   +---
448471SGiacomo.Gabrielli@arm.com   | arg[n-1]
458471SGiacomo.Gabrielli@arm.com   | ..
468471SGiacomo.Gabrielli@arm.com   | arg[0]
478471SGiacomo.Gabrielli@arm.com   +---
488471SGiacomo.Gabrielli@arm.com   | ret pc	=== `qt_vstart'
498471SGiacomo.Gabrielli@arm.com   +---
508471SGiacomo.Gabrielli@arm.com   | %ebp	=== `startup'
518471SGiacomo.Gabrielli@arm.com   | %esi	=== `cleanup'
528471SGiacomo.Gabrielli@arm.com   | %edi	=== `pt'
538471SGiacomo.Gabrielli@arm.com   | %ebx	=== `vuserf'		<--- qt_t.sp
548471SGiacomo.Gabrielli@arm.com   +---
558471SGiacomo.Gabrielli@arm.com
568471SGiacomo.Gabrielli@arm.com   When a varargs thread is started, it ``returns'' to the `qt_vstart'
578471SGiacomo.Gabrielli@arm.com   startup code.  The startup code calls the appropriate functions. */
588471SGiacomo.Gabrielli@arm.com
598471SGiacomo.Gabrielli@arm.com
608471SGiacomo.Gabrielli@arm.com/* What to do to start a varargs thread running. */
618471SGiacomo.Gabrielli@arm.comextern void qt_vstart (void);
628471SGiacomo.Gabrielli@arm.com
638471SGiacomo.Gabrielli@arm.com
648471SGiacomo.Gabrielli@arm.com/* Hold 4 saved regs plus two return pcs (qt_error, qt_start) plus
658471SGiacomo.Gabrielli@arm.com   three args. */
668471SGiacomo.Gabrielli@arm.com#define QUICKTHREADS_STKBASE	(13 * 4)
678471SGiacomo.Gabrielli@arm.com
688471SGiacomo.Gabrielli@arm.com/* Hold 4 saved regs plus one return pc (qt_vstart). */
698471SGiacomo.Gabrielli@arm.com#define QUICKTHREADS_VSTKBASE	(5 * 4)
708471SGiacomo.Gabrielli@arm.com
718471SGiacomo.Gabrielli@arm.com
728471SGiacomo.Gabrielli@arm.com/* Stack must be 16-byte aligned at function call instr. (SSE data support) */
738471SGiacomo.Gabrielli@arm.com#define QUICKTHREADS_STKALIGN	(16)
748471SGiacomo.Gabrielli@arm.com
758471SGiacomo.Gabrielli@arm.com
768471SGiacomo.Gabrielli@arm.com/* Where to place various arguments. */
778471SGiacomo.Gabrielli@arm.com#define QUICKTHREADS_ONLY_INDEX	(QUICKTHREADS_PC)
788471SGiacomo.Gabrielli@arm.com#define QUICKTHREADS_USER_INDEX	(QUICKTHREADS_ARG2)
798471SGiacomo.Gabrielli@arm.com#define QUICKTHREADS_ARGT_INDEX	(QUICKTHREADS_ARG1)
808471SGiacomo.Gabrielli@arm.com#define QUICKTHREADS_ARGU_INDEX	(QUICKTHREADS_ARG0)
818471SGiacomo.Gabrielli@arm.com
828471SGiacomo.Gabrielli@arm.com#define QUICKTHREADS_VSTARTUP_INDEX	(QUICKTHREADS_EBP)
838471SGiacomo.Gabrielli@arm.com#define QUICKTHREADS_VUSERF_INDEX		(QUICKTHREADS_EBX)
848471SGiacomo.Gabrielli@arm.com#define QUICKTHREADS_VCLEANUP_INDEX	(QUICKTHREADS_ESI)
858471SGiacomo.Gabrielli@arm.com#define QUICKTHREADS_VARGT_INDEX		(QUICKTHREADS_EDI)
868471SGiacomo.Gabrielli@arm.com
878471SGiacomo.Gabrielli@arm.com
888471SGiacomo.Gabrielli@arm.com#define QUICKTHREADS_EBX        0
898471SGiacomo.Gabrielli@arm.com#define QUICKTHREADS_EDI        1
908471SGiacomo.Gabrielli@arm.com#define QUICKTHREADS_ESI        2
918471SGiacomo.Gabrielli@arm.com#define QUICKTHREADS_EBP        3
928471SGiacomo.Gabrielli@arm.com#define QUICKTHREADS_POP0       4
938471SGiacomo.Gabrielli@arm.com#define QUICKTHREADS_POP1       5
948471SGiacomo.Gabrielli@arm.com#define QUICKTHREADS_POP2       6
958471SGiacomo.Gabrielli@arm.com#define QUICKTHREADS_PC         7
968471SGiacomo.Gabrielli@arm.com/* The following are defined only for non-varargs. */
978471SGiacomo.Gabrielli@arm.com#define QUICKTHREADS_POPE       8
988471SGiacomo.Gabrielli@arm.com#define QUICKTHREADS_ARG0       9
998471SGiacomo.Gabrielli@arm.com#define QUICKTHREADS_ARG1      10
1008471SGiacomo.Gabrielli@arm.com#define QUICKTHREADS_ARG2      11
1018471SGiacomo.Gabrielli@arm.com#define QUICKTHREADS_RPC       12
1028471SGiacomo.Gabrielli@arm.com
1038471SGiacomo.Gabrielli@arm.com
1048471SGiacomo.Gabrielli@arm.com/* Stack grows down.  The top of the stack is the first thing to
1058471SGiacomo.Gabrielli@arm.com   pop off (preincrement, postdecrement). */
1068471SGiacomo.Gabrielli@arm.com#define QUICKTHREADS_GROW_DOWN
1078471SGiacomo.Gabrielli@arm.com
1088471SGiacomo.Gabrielli@arm.comextern void qt_error (void);
1098471SGiacomo.Gabrielli@arm.com
1108471SGiacomo.Gabrielli@arm.com/* For correct 16-byte stack alignment (auto-relocatable functions) */
1118471SGiacomo.Gabrielli@arm.comextern void qt_tramp (void);
1128471SGiacomo.Gabrielli@arm.comextern void qt_align (void);
1138471SGiacomo.Gabrielli@arm.com
1148471SGiacomo.Gabrielli@arm.com/* Push on the error return address and the alignment/trampoline functions. */
1158471SGiacomo.Gabrielli@arm.com#define QUICKTHREADS_ARGS_MD(sto) \
1168471SGiacomo.Gabrielli@arm.com  (QUICKTHREADS_SPUT (sto, QUICKTHREADS_POP0, qt_align), \
1178471SGiacomo.Gabrielli@arm.com   QUICKTHREADS_SPUT (sto, QUICKTHREADS_POP1, qt_align), \
1188471SGiacomo.Gabrielli@arm.com   QUICKTHREADS_SPUT (sto, QUICKTHREADS_POP2, qt_align), \
1198471SGiacomo.Gabrielli@arm.com   QUICKTHREADS_SPUT (sto, QUICKTHREADS_POPE, qt_tramp), \
1208471SGiacomo.Gabrielli@arm.com   QUICKTHREADS_SPUT (sto, QUICKTHREADS_RPC, qt_error))
1218471SGiacomo.Gabrielli@arm.com
1228471SGiacomo.Gabrielli@arm.com
1238471SGiacomo.Gabrielli@arm.com/* When varargs are pushed, allocate space for all the args. */
1248471SGiacomo.Gabrielli@arm.com#define QUICKTHREADS_VARGS_MD0(sto, nbytes) \
1258471SGiacomo.Gabrielli@arm.com  ((qt_t *)(((char *)(sto)) - QUICKTHREADS_STKROUNDUP(nbytes)))
1268471SGiacomo.Gabrielli@arm.com
1278471SGiacomo.Gabrielli@arm.com#define QUICKTHREADS_VARGS_MD1(sto) \
1288471SGiacomo.Gabrielli@arm.com  (QUICKTHREADS_SPUT (sto, QUICKTHREADS_PC, qt_vstart))
1298471SGiacomo.Gabrielli@arm.com
1308471SGiacomo.Gabrielli@arm.com#define QUICKTHREADS_VARGS_DEFAULT
1318471SGiacomo.Gabrielli@arm.com
1328471SGiacomo.Gabrielli@arm.com#endif /* QUICKTHREADS_386_H */
1338471SGiacomo.Gabrielli@arm.com