112027Sjungma@eit.uni-kl.de/* powerpc-sys5.s -- assembly support. */ 212027Sjungma@eit.uni-kl.de 312027Sjungma@eit.uni-kl.de/* 412027Sjungma@eit.uni-kl.de * QuickThreads -- Threads-building toolkit. 512027Sjungma@eit.uni-kl.de * Copyright (c) 1993 by David Keppel 612027Sjungma@eit.uni-kl.de * 712027Sjungma@eit.uni-kl.de * Permission to use, copy, modify and distribute this software and 812027Sjungma@eit.uni-kl.de * its documentation for any purpose and without fee is hereby 912027Sjungma@eit.uni-kl.de * granted, provided that the above copyright notice and this notice 1012027Sjungma@eit.uni-kl.de * appear in all copies. This software is provided as a 1112027Sjungma@eit.uni-kl.de * proof-of-concept and for demonstration purposes; there is no 1212027Sjungma@eit.uni-kl.de * representation about the suitability of this software for any 1312027Sjungma@eit.uni-kl.de * purpose. 1412027Sjungma@eit.uni-kl.de 1512027Sjungma@eit.uni-kl.de 1612027Sjungma@eit.uni-kl.de * PowerPC-System V thread switching module. 1712027Sjungma@eit.uni-kl.de * 1812027Sjungma@eit.uni-kl.de * This software is largely based on the original PowerPC-Linux porting 1912027Sjungma@eit.uni-kl.de * developed by Ken Aaker <kenaaker@silverbacksystems.com> 2012027Sjungma@eit.uni-kl.de * 2112027Sjungma@eit.uni-kl.de * Marco Bucci <marco.bucci@inwind.it> 2212027Sjungma@eit.uni-kl.de * December 2002 2312027Sjungma@eit.uni-kl.de * 2412027Sjungma@eit.uni-kl.de */ 2512027Sjungma@eit.uni-kl.de 2612027Sjungma@eit.uni-kl.de 2712027Sjungma@eit.uni-kl.de/* 2812027Sjungma@eit.uni-kl.de * 2912027Sjungma@eit.uni-kl.de * PowerPC Register convections: 3012027Sjungma@eit.uni-kl.de * 3112027Sjungma@eit.uni-kl.de * r0 volatile 3212027Sjungma@eit.uni-kl.de * r1 SP 3312027Sjungma@eit.uni-kl.de * r2 system reserved 3412027Sjungma@eit.uni-kl.de * r3-r4 volatile for parameter passing and function return 3512027Sjungma@eit.uni-kl.de * r5-r10 volatile for parameter passing 3612027Sjungma@eit.uni-kl.de * r11-r12 volatile 3712027Sjungma@eit.uni-kl.de * r13-r14 non volatile registers 3812027Sjungma@eit.uni-kl.de * f0 volatile 3912027Sjungma@eit.uni-kl.de * f1 volatile for parameter passing and function return 4012027Sjungma@eit.uni-kl.de * f2-f13 volatile for parameter passing 4112027Sjungma@eit.uni-kl.de * f14-f31 non volatile 4212027Sjungma@eit.uni-kl.de * 4312027Sjungma@eit.uni-kl.de * cr2-cr4 non volatile 4412027Sjungma@eit.uni-kl.de * 4512027Sjungma@eit.uni-kl.de * 4612027Sjungma@eit.uni-kl.de * See on the heather file for more documentation. 4712027Sjungma@eit.uni-kl.de * 4812027Sjungma@eit.uni-kl.de * 4912027Sjungma@eit.uni-kl.de * 5012027Sjungma@eit.uni-kl.de * IMPLEMENTATION NOTES 5112027Sjungma@eit.uni-kl.de * 5212027Sjungma@eit.uni-kl.de * 5312027Sjungma@eit.uni-kl.de * 1) Condition register saving 5412027Sjungma@eit.uni-kl.de * On most machines, the condition code register is caller-save. 5512027Sjungma@eit.uni-kl.de * On the PPC, the condition code register is callee-save, so the 5612027Sjungma@eit.uni-kl.de * thread context switch must preserve it. 5712027Sjungma@eit.uni-kl.de * 5812027Sjungma@eit.uni-kl.de * 5912027Sjungma@eit.uni-kl.de * 2) Floating point registers saving 6012027Sjungma@eit.uni-kl.de * On resuming a thread, floating point registers are or not restored just 6112027Sjungma@eit.uni-kl.de * depending on which block routine suspended the thread (i.e. regardless 6212027Sjungma@eit.uni-kl.de * whether "qt_block", "qt_blocki" or "qt_abort" is used to resume it). 6312027Sjungma@eit.uni-kl.de * This behaviour is obtained by implementing "qt_block" by means af a nested 6412027Sjungma@eit.uni-kl.de * call to "qt_blocki". As a result, the blocking of a thread always goes 6512027Sjungma@eit.uni-kl.de * and returns through "qt_blocki and, if a thread was blocked by "qt_block", 6612027Sjungma@eit.uni-kl.de * its execution resumes from the floating point restoring code on exit 6712027Sjungma@eit.uni-kl.de * of "qt_block". 6812027Sjungma@eit.uni-kl.de * 6912027Sjungma@eit.uni-kl.de * Thanks to David Keppel that explained me this "simple" trick. 7012027Sjungma@eit.uni-kl.de * 7112027Sjungma@eit.uni-kl.de * 7212027Sjungma@eit.uni-kl.de * 3) C languace code debugging 7312027Sjungma@eit.uni-kl.de * The original version of this software was developed and debugged under 7412027Sjungma@eit.uni-kl.de * MacOS X using the Metrowerks Code Warrior PPC integrated assembler. 7512027Sjungma@eit.uni-kl.de * It could be still used with a C inline assembler by means of a suitable 7612027Sjungma@eit.uni-kl.de * file to include it. 7712027Sjungma@eit.uni-kl.de * In order to avoid "copy and paste" bugs, and make easyer the maintaining, 7812027Sjungma@eit.uni-kl.de * I made the minimal changes, so you can find some strange code as: 7912027Sjungma@eit.uni-kl.de * 8012027Sjungma@eit.uni-kl.de * #if 0 8112027Sjungma@eit.uni-kl.de * .if 0 8212027Sjungma@eit.uni-kl.de * C code here 8312027Sjungma@eit.uni-kl.de * .endif 8412027Sjungma@eit.uni-kl.de * #endif 8512027Sjungma@eit.uni-kl.de * 8612027Sjungma@eit.uni-kl.de * This is just to embed some C code that is needed by the Code Warrior 8712027Sjungma@eit.uni-kl.de * integrated assembler. 8812027Sjungma@eit.uni-kl.de * 8912027Sjungma@eit.uni-kl.de * 9012027Sjungma@eit.uni-kl.de * 4) Assembly constants generation 9112027Sjungma@eit.uni-kl.de * Constants used in the assembly code are generated by running 9212027Sjungma@eit.uni-kl.de * the C code in the sequel (commented). It uses the C macros declared in 9312027Sjungma@eit.uni-kl.de * the C heather in order to guarantee that the C interface and the assebly 9412027Sjungma@eit.uni-kl.de * code are "aligned". I avoided the use of an assebler preprocessor since 9512027Sjungma@eit.uni-kl.de * they are not so standard and moreover using macro espressions makes the 9612027Sjungma@eit.uni-kl.de * assembly debugging more difficult. 9712027Sjungma@eit.uni-kl.de * 9812027Sjungma@eit.uni-kl.de * 9912027Sjungma@eit.uni-kl.de 10012027Sjungma@eit.uni-kl.de 10112027Sjungma@eit.uni-kl.de#include <iostream> 10212027Sjungma@eit.uni-kl.de#include "powerpc_sys5.h" 10312027Sjungma@eit.uni-kl.de 10412027Sjungma@eit.uni-kl.deint main() 10512027Sjungma@eit.uni-kl.de{ 10612027Sjungma@eit.uni-kl.de using namespace std; 10712027Sjungma@eit.uni-kl.de 10812027Sjungma@eit.uni-kl.de int i; 10912027Sjungma@eit.uni-kl.de 11012027Sjungma@eit.uni-kl.de cout << ".set LR_SAVE, " << PPC_LR_SAVE << endl; 11112027Sjungma@eit.uni-kl.de cout << ".set BLOCKI_FSIZE, " << QUICKTHREADS_BLOCKI_FRAME_SIZE << endl; 11212027Sjungma@eit.uni-kl.de cout << ".set BLOCKI_CR_SAVE, " << QUICKTHREADS_BLOCKI_CR_SAVE << endl; 11312027Sjungma@eit.uni-kl.de cout << ".set BLOCK_FSIZE, " << QUICKTHREADS_BLOCK_FRAME_SIZE << endl; 11412027Sjungma@eit.uni-kl.de 11512027Sjungma@eit.uni-kl.de cout << endl; 11612027Sjungma@eit.uni-kl.de for(i=0; i<12; i++) 11712027Sjungma@eit.uni-kl.de cout << ".set PAR_" << i << ", " << PPC_PAR(i) << endl; 11812027Sjungma@eit.uni-kl.de 11912027Sjungma@eit.uni-kl.de cout << endl; 12012027Sjungma@eit.uni-kl.de i = 13; 12112027Sjungma@eit.uni-kl.de cout << ".set GPR_SAVE_" << i << ", " << QUICKTHREADS_BLOCKI_GPR_SAVE(i) << endl; 12212027Sjungma@eit.uni-kl.de 12312027Sjungma@eit.uni-kl.de cout << endl; 12412027Sjungma@eit.uni-kl.de for(i=31; i>13; i--) 12512027Sjungma@eit.uni-kl.de cout << ".set FPR_SAVE_" << i << ", " << QUICKTHREADS_BLOCK_FPR_SAVE(i) << endl; 12612027Sjungma@eit.uni-kl.de 12712027Sjungma@eit.uni-kl.de cout << endl; 12812027Sjungma@eit.uni-kl.de cout << ".set VARGS_BKOFF, " << QUICKTHREADS_VARGS_BKOFF << endl; 12912027Sjungma@eit.uni-kl.de 13012027Sjungma@eit.uni-kl.de 13112027Sjungma@eit.uni-kl.de cout << endl << endl << endl; 13212027Sjungma@eit.uni-kl.de 13312027Sjungma@eit.uni-kl.de for(i=31; i>13; i--) 13412027Sjungma@eit.uni-kl.de cout << "\tstfd\tf" << i << ",FPR_SAVE_" << i << "(%r1)" << endl; 13512027Sjungma@eit.uni-kl.de 13612027Sjungma@eit.uni-kl.de cout << endl; 13712027Sjungma@eit.uni-kl.de for(i=31; i>13; i--) 13812027Sjungma@eit.uni-kl.de cout << "\tlfd \tf" << i << ",FPR_SAVE_" << i << "(%r1)" << endl; 13912027Sjungma@eit.uni-kl.de 14012027Sjungma@eit.uni-kl.de cout << endl << endl << endl; 14112027Sjungma@eit.uni-kl.de 14212027Sjungma@eit.uni-kl.de 14312027Sjungma@eit.uni-kl.de return 0; 14412027Sjungma@eit.uni-kl.de} 14512027Sjungma@eit.uni-kl.de 14612027Sjungma@eit.uni-kl.de 14712027Sjungma@eit.uni-kl.de 14812027Sjungma@eit.uni-kl.de * 14912027Sjungma@eit.uni-kl.de * 15012027Sjungma@eit.uni-kl.de * 15112027Sjungma@eit.uni-kl.de */ 15212027Sjungma@eit.uni-kl.de 15312027Sjungma@eit.uni-kl.de 15412027Sjungma@eit.uni-kl.de#if 0 15512027Sjungma@eit.uni-kl.de 15612027Sjungma@eit.uni-kl.de .text 15712027Sjungma@eit.uni-kl.de .align 4 15812027Sjungma@eit.uni-kl.de 15912027Sjungma@eit.uni-kl.de .globl qt_block 16012027Sjungma@eit.uni-kl.de .globl _qt_block 16112027Sjungma@eit.uni-kl.de .globl qt_blocki 16212027Sjungma@eit.uni-kl.de .globl _qt_blocki 16312027Sjungma@eit.uni-kl.de .globl qt_abort 16412027Sjungma@eit.uni-kl.de .globl _qt_abort 16512027Sjungma@eit.uni-kl.de .globl qt_start 16612027Sjungma@eit.uni-kl.de .globl _qt_start 16712027Sjungma@eit.uni-kl.de .globl qt_vstart 16812027Sjungma@eit.uni-kl.de .globl _qt_vstart 16912027Sjungma@eit.uni-kl.de 17012027Sjungma@eit.uni-kl.de 17112027Sjungma@eit.uni-kl.de.set LR_SAVE, 4 17212027Sjungma@eit.uni-kl.de.set BLOCKI_FSIZE, 96 17312027Sjungma@eit.uni-kl.de.set BLOCKI_CR_SAVE, 8 /* CR is saved into the callee's stack frame */ 17412027Sjungma@eit.uni-kl.de.set BLOCK_FSIZE, 160 17512027Sjungma@eit.uni-kl.de 17612027Sjungma@eit.uni-kl.de.set PAR_0, 8 17712027Sjungma@eit.uni-kl.de.set PAR_1, 12 17812027Sjungma@eit.uni-kl.de.set PAR_2, 16 17912027Sjungma@eit.uni-kl.de.set PAR_3, 20 18012027Sjungma@eit.uni-kl.de.set PAR_4, 24 18112027Sjungma@eit.uni-kl.de.set PAR_5, 28 18212027Sjungma@eit.uni-kl.de.set PAR_6, 32 18312027Sjungma@eit.uni-kl.de.set PAR_7, 36 18412027Sjungma@eit.uni-kl.de.set PAR_8, 40 18512027Sjungma@eit.uni-kl.de.set PAR_9, 44 18612027Sjungma@eit.uni-kl.de.set PAR_10, 48 18712027Sjungma@eit.uni-kl.de.set PAR_11, 52 18812027Sjungma@eit.uni-kl.de 18912027Sjungma@eit.uni-kl.de.set GPR_SAVE_13, 20 19012027Sjungma@eit.uni-kl.de 19112027Sjungma@eit.uni-kl.de.set FPR_SAVE_31, 152 19212027Sjungma@eit.uni-kl.de.set FPR_SAVE_30, 144 19312027Sjungma@eit.uni-kl.de.set FPR_SAVE_29, 136 19412027Sjungma@eit.uni-kl.de.set FPR_SAVE_28, 128 19512027Sjungma@eit.uni-kl.de.set FPR_SAVE_27, 120 19612027Sjungma@eit.uni-kl.de.set FPR_SAVE_26, 112 19712027Sjungma@eit.uni-kl.de.set FPR_SAVE_25, 104 19812027Sjungma@eit.uni-kl.de.set FPR_SAVE_24, 96 19912027Sjungma@eit.uni-kl.de.set FPR_SAVE_23, 88 20012027Sjungma@eit.uni-kl.de.set FPR_SAVE_22, 80 20112027Sjungma@eit.uni-kl.de.set FPR_SAVE_21, 72 20212027Sjungma@eit.uni-kl.de.set FPR_SAVE_20, 64 20312027Sjungma@eit.uni-kl.de.set FPR_SAVE_19, 56 20412027Sjungma@eit.uni-kl.de.set FPR_SAVE_18, 48 20512027Sjungma@eit.uni-kl.de.set FPR_SAVE_17, 40 20612027Sjungma@eit.uni-kl.de.set FPR_SAVE_16, 32 20712027Sjungma@eit.uni-kl.de.set FPR_SAVE_15, 24 20812027Sjungma@eit.uni-kl.de.set FPR_SAVE_14, 16 20912027Sjungma@eit.uni-kl.de 21012027Sjungma@eit.uni-kl.de 21112027Sjungma@eit.uni-kl.de 21212027Sjungma@eit.uni-kl.de 21312027Sjungma@eit.uni-kl.de/* various offsets used by "qt_varg" */ 21412027Sjungma@eit.uni-kl.de.set P_T, PAR_0 21512027Sjungma@eit.uni-kl.de.set P_STARTUP, PAR_1 21612027Sjungma@eit.uni-kl.de.set P_USERF, PAR_2 21712027Sjungma@eit.uni-kl.de.set P_CLEANUP, PAR_3 21812027Sjungma@eit.uni-kl.de /* the offset used to move back the linkage area to be adiacent to 21912027Sjungma@eit.uni-kl.de * the variant argument list before calling "userf(...). 22012027Sjungma@eit.uni-kl.de * Skip "t", "startup", "userf", "cleanup" and first 22112027Sjungma@eit.uni-kl.de * 8 parameters (since they are passed via registers) */ 22212027Sjungma@eit.uni-kl.de.set VARGS_BKOFF, 48 22312027Sjungma@eit.uni-kl.de 22412027Sjungma@eit.uni-kl.de /* location where "t" and "cleanup" are saved (with respect of 22512027Sjungma@eit.uni-kl.de * the stack frame base) */ 22612027Sjungma@eit.uni-kl.de.set P_T_SAVE, -4 22712027Sjungma@eit.uni-kl.de.set P_CLEANUP_SAVE, -8 22812027Sjungma@eit.uni-kl.de 22912027Sjungma@eit.uni-kl.de#endif 23012027Sjungma@eit.uni-kl.de 23112027Sjungma@eit.uni-kl.de 23212027Sjungma@eit.uni-kl.de 23312027Sjungma@eit.uni-kl.de/* Block the current thread saving all integer non volatile registers and 23412027Sjungma@eit.uni-kl.de * start a new thread. 23512027Sjungma@eit.uni-kl.de */ 23612027Sjungma@eit.uni-kl.de#if 0 23712027Sjungma@eit.uni-kl.de.if 0 23812027Sjungma@eit.uni-kl.de#endif 23912027Sjungma@eit.uni-kl.devoid *qt_blocki (void *helper, void *a0, void *a1, void *newthread); 24012027Sjungma@eit.uni-kl.deasm void *qt_blocki (void *helper, void *a0, void *a1, void *newthread) 24112027Sjungma@eit.uni-kl.de{ 24212027Sjungma@eit.uni-kl.de#if 0 24312027Sjungma@eit.uni-kl.de.endif 24412027Sjungma@eit.uni-kl.de#endif 24512027Sjungma@eit.uni-kl.de 24612027Sjungma@eit.uni-kl.de#if 0 24712027Sjungma@eit.uni-kl.deqt_blocki: 24812027Sjungma@eit.uni-kl.de_qt_blocki: 24912027Sjungma@eit.uni-kl.de#endif 25012027Sjungma@eit.uni-kl.de/* prolog code */ 25112027Sjungma@eit.uni-kl.de stwu %r1,-BLOCKI_FSIZE(%r1) /* allocate the stack frame */ 25212027Sjungma@eit.uni-kl.de mflr %r0 /* return addr in r0 */ 25312027Sjungma@eit.uni-kl.de mfcr %r11 /* CR in r11 */ 25412027Sjungma@eit.uni-kl.de stw %r0,LR_SAVE+BLOCKI_FSIZE(%r1) /* save return addr in the stack */ 25512027Sjungma@eit.uni-kl.de stw %r11,BLOCKI_CR_SAVE(%r1) /* save CR in the stack */ 25612027Sjungma@eit.uni-kl.de stmw %r13,GPR_SAVE_13(%r1) /* save non-volatile reg */ 25712027Sjungma@eit.uni-kl.de 25812027Sjungma@eit.uni-kl.de/* call helper(qt_t *old, void *a0, void *a1) */ 25912027Sjungma@eit.uni-kl.de mtlr %r3 /* "helper" addr in the link reg */ 26012027Sjungma@eit.uni-kl.de mr %r3,%r1 /* current thread (i.e. the SP) in arg "old" */ 26112027Sjungma@eit.uni-kl.de mr %r1,%r6 /* swap to the new thread (i.e. to its SP) */ 26212027Sjungma@eit.uni-kl.de blrl /* jump to "helper" */ 26312027Sjungma@eit.uni-kl.de/* the "helper" return value is returned (since r3 is not changed) */ 26412027Sjungma@eit.uni-kl.de 26512027Sjungma@eit.uni-kl.de/* epilog code: return to the new thread's "qt_blocki" caller */ 26612027Sjungma@eit.uni-kl.de lmw %r13,GPR_SAVE_13(%r1) /* restore non-volatile reg */ 26712027Sjungma@eit.uni-kl.de lwz %r0,LR_SAVE+BLOCKI_FSIZE(%r1) /* recover return addr */ 26812027Sjungma@eit.uni-kl.de lwz %r11,BLOCKI_CR_SAVE(%r1) /* recover CR */ 26912027Sjungma@eit.uni-kl.de mtlr %r0 /* return address in the link reg */ 27012027Sjungma@eit.uni-kl.de mtcr %r11 /* restore CR */ 27112027Sjungma@eit.uni-kl.de addi %r1,%r1,BLOCKI_FSIZE /* free the stack frame */ 27212027Sjungma@eit.uni-kl.de blr /* return */ 27312027Sjungma@eit.uni-kl.de 27412027Sjungma@eit.uni-kl.de#if 0 27512027Sjungma@eit.uni-kl.de.if 0 27612027Sjungma@eit.uni-kl.de#endif 27712027Sjungma@eit.uni-kl.de} 27812027Sjungma@eit.uni-kl.de#if 0 27912027Sjungma@eit.uni-kl.de.endif 28012027Sjungma@eit.uni-kl.de#endif 28112027Sjungma@eit.uni-kl.de 28212027Sjungma@eit.uni-kl.de 28312027Sjungma@eit.uni-kl.de 28412027Sjungma@eit.uni-kl.de/* Abort the current thread and start a new thread. 28512027Sjungma@eit.uni-kl.de */ 28612027Sjungma@eit.uni-kl.de#if 0 28712027Sjungma@eit.uni-kl.de.if 0 28812027Sjungma@eit.uni-kl.de#endif 28912027Sjungma@eit.uni-kl.devoid qt_abort (void *helper, void *a0, void *a1, void *newthread); 29012027Sjungma@eit.uni-kl.deasm void qt_abort (void *helper, void *a0, void *a1, void *newthread) 29112027Sjungma@eit.uni-kl.de{ 29212027Sjungma@eit.uni-kl.de#if 0 29312027Sjungma@eit.uni-kl.de.endif 29412027Sjungma@eit.uni-kl.de#endif 29512027Sjungma@eit.uni-kl.de 29612027Sjungma@eit.uni-kl.de#if 0 29712027Sjungma@eit.uni-kl.deqt_abort: 29812027Sjungma@eit.uni-kl.de_qt_abort: 29912027Sjungma@eit.uni-kl.de#endif 30012027Sjungma@eit.uni-kl.de/* prolog code */ 30112027Sjungma@eit.uni-kl.de/* there is no prolog. It will never come back */ 30212027Sjungma@eit.uni-kl.de 30312027Sjungma@eit.uni-kl.de/* call helper(qt_t *old, void *a0, void *a1) */ 30412027Sjungma@eit.uni-kl.de mtlr %r3 /* "helper" addr in the link reg */ 30512027Sjungma@eit.uni-kl.de mr %r1,%r6 /* swap to the new thread (i.e. to its SP) */ 30612027Sjungma@eit.uni-kl.de/* we don't need to set "old", we can pass just garbage. Actually, since r3 30712027Sjungma@eit.uni-kl.de is not changed, "old" is set to "helper" (don't care) */ 30812027Sjungma@eit.uni-kl.de blrl /* call "helper" */ 30912027Sjungma@eit.uni-kl.de/* the "helper" return value is returned (since r3 is not changed) */ 31012027Sjungma@eit.uni-kl.de 31112027Sjungma@eit.uni-kl.de/* epilog code: return to the new thread's "qt_blocki" caller */ 31212027Sjungma@eit.uni-kl.de lmw %r13,GPR_SAVE_13(%r1) /* restore non-volatile reg */ 31312027Sjungma@eit.uni-kl.de lwz %r0,LR_SAVE+BLOCKI_FSIZE(%r1) /* recover return addr */ 31412027Sjungma@eit.uni-kl.de lwz %r11,BLOCKI_CR_SAVE(%r1) /* recover CR */ 31512027Sjungma@eit.uni-kl.de mtlr %r0 /* return address in the link reg */ 31612027Sjungma@eit.uni-kl.de mtcr %r11 /* restore CR */ 31712027Sjungma@eit.uni-kl.de addi %r1,%r1,BLOCKI_FSIZE /* free the stack frame */ 31812027Sjungma@eit.uni-kl.de blr /* return */ 31912027Sjungma@eit.uni-kl.de 32012027Sjungma@eit.uni-kl.de#if 0 32112027Sjungma@eit.uni-kl.de.if 0 32212027Sjungma@eit.uni-kl.de#endif 32312027Sjungma@eit.uni-kl.de} 32412027Sjungma@eit.uni-kl.de#if 0 32512027Sjungma@eit.uni-kl.de.endif 32612027Sjungma@eit.uni-kl.de#endif 32712027Sjungma@eit.uni-kl.de 32812027Sjungma@eit.uni-kl.de 32912027Sjungma@eit.uni-kl.de 33012027Sjungma@eit.uni-kl.de/* Block the current thread saving all non volatile registers and start 33112027Sjungma@eit.uni-kl.de * a new thread. 33212027Sjungma@eit.uni-kl.de */ 33312027Sjungma@eit.uni-kl.de#if 0 33412027Sjungma@eit.uni-kl.de.if 0 33512027Sjungma@eit.uni-kl.de#endif 33612027Sjungma@eit.uni-kl.devoid *qt_block (void *helper, void *a0, void *a1, void *newthread); 33712027Sjungma@eit.uni-kl.deasm void *qt_block (void *helper, void *a0, void *a1, void *newthread) 33812027Sjungma@eit.uni-kl.de{ 33912027Sjungma@eit.uni-kl.de#if 0 34012027Sjungma@eit.uni-kl.de.endif 34112027Sjungma@eit.uni-kl.de#endif 34212027Sjungma@eit.uni-kl.de 34312027Sjungma@eit.uni-kl.de# if 0 34412027Sjungma@eit.uni-kl.deqt_block: 34512027Sjungma@eit.uni-kl.de_qt_block: 34612027Sjungma@eit.uni-kl.de#endif 34712027Sjungma@eit.uni-kl.de/* prolog code */ 34812027Sjungma@eit.uni-kl.de stwu %r1,-BLOCK_FSIZE(%r1) /* allocate the stack frame */ 34912027Sjungma@eit.uni-kl.de mflr %r0 /* return addr in r0 */ 35012027Sjungma@eit.uni-kl.de stw %r0,LR_SAVE+BLOCK_FSIZE(%r1) /* save return addr in the stack */ 35112027Sjungma@eit.uni-kl.de 35212027Sjungma@eit.uni-kl.de/* save non-volatile fp reg */ 35312027Sjungma@eit.uni-kl.de stfd %f31,FPR_SAVE_31(%r1) 35412027Sjungma@eit.uni-kl.de stfd %f30,FPR_SAVE_30(%r1) 35512027Sjungma@eit.uni-kl.de stfd %f29,FPR_SAVE_29(%r1) 35612027Sjungma@eit.uni-kl.de stfd %f28,FPR_SAVE_28(%r1) 35712027Sjungma@eit.uni-kl.de stfd %f27,FPR_SAVE_27(%r1) 35812027Sjungma@eit.uni-kl.de stfd %f26,FPR_SAVE_26(%r1) 35912027Sjungma@eit.uni-kl.de stfd %f25,FPR_SAVE_25(%r1) 36012027Sjungma@eit.uni-kl.de stfd %f24,FPR_SAVE_24(%r1) 36112027Sjungma@eit.uni-kl.de stfd %f23,FPR_SAVE_23(%r1) 36212027Sjungma@eit.uni-kl.de stfd %f22,FPR_SAVE_22(%r1) 36312027Sjungma@eit.uni-kl.de stfd %f21,FPR_SAVE_21(%r1) 36412027Sjungma@eit.uni-kl.de stfd %f20,FPR_SAVE_20(%r1) 36512027Sjungma@eit.uni-kl.de stfd %f19,FPR_SAVE_19(%r1) 36612027Sjungma@eit.uni-kl.de stfd %f18,FPR_SAVE_18(%r1) 36712027Sjungma@eit.uni-kl.de stfd %f17,FPR_SAVE_17(%r1) 36812027Sjungma@eit.uni-kl.de stfd %f16,FPR_SAVE_16(%r1) 36912027Sjungma@eit.uni-kl.de stfd %f15,FPR_SAVE_15(%r1) 37012027Sjungma@eit.uni-kl.de stfd %f14,FPR_SAVE_14(%r1) 37112027Sjungma@eit.uni-kl.de/* block the thread */ 37212027Sjungma@eit.uni-kl.de bl qt_blocki 37312027Sjungma@eit.uni-kl.de/* the thread is going to be resumed */ 37412027Sjungma@eit.uni-kl.de/* restore non-volatile fp reg */ 37512027Sjungma@eit.uni-kl.de lfd %f31,FPR_SAVE_31(%r1) 37612027Sjungma@eit.uni-kl.de lfd %f30,FPR_SAVE_30(%r1) 37712027Sjungma@eit.uni-kl.de lfd %f29,FPR_SAVE_29(%r1) 37812027Sjungma@eit.uni-kl.de lfd %f28,FPR_SAVE_28(%r1) 37912027Sjungma@eit.uni-kl.de lfd %f27,FPR_SAVE_27(%r1) 38012027Sjungma@eit.uni-kl.de lfd %f26,FPR_SAVE_26(%r1) 38112027Sjungma@eit.uni-kl.de lfd %f25,FPR_SAVE_25(%r1) 38212027Sjungma@eit.uni-kl.de lfd %f24,FPR_SAVE_24(%r1) 38312027Sjungma@eit.uni-kl.de lfd %f23,FPR_SAVE_23(%r1) 38412027Sjungma@eit.uni-kl.de lfd %f22,FPR_SAVE_22(%r1) 38512027Sjungma@eit.uni-kl.de lfd %f21,FPR_SAVE_21(%r1) 38612027Sjungma@eit.uni-kl.de lfd %f20,FPR_SAVE_20(%r1) 38712027Sjungma@eit.uni-kl.de lfd %f19,FPR_SAVE_19(%r1) 38812027Sjungma@eit.uni-kl.de lfd %f18,FPR_SAVE_18(%r1) 38912027Sjungma@eit.uni-kl.de lfd %f17,FPR_SAVE_17(%r1) 39012027Sjungma@eit.uni-kl.de lfd %f16,FPR_SAVE_16(%r1) 39112027Sjungma@eit.uni-kl.de lfd %f15,FPR_SAVE_15(%r1) 39212027Sjungma@eit.uni-kl.de lfd %f14,FPR_SAVE_14(%r1) 39312027Sjungma@eit.uni-kl.de 39412027Sjungma@eit.uni-kl.de lwz %r0,LR_SAVE+BLOCK_FSIZE(%r1) /* recover return addr */ 39512027Sjungma@eit.uni-kl.de mtlr %r0 /* return address in the link reg */ 39612027Sjungma@eit.uni-kl.de addi %r1,%r1,BLOCK_FSIZE /* free the stack frame */ 39712027Sjungma@eit.uni-kl.de blr /* return */ 39812027Sjungma@eit.uni-kl.de 39912027Sjungma@eit.uni-kl.de#if 0 40012027Sjungma@eit.uni-kl.de.if 0 40112027Sjungma@eit.uni-kl.de#endif 40212027Sjungma@eit.uni-kl.de} 40312027Sjungma@eit.uni-kl.de#if 0 40412027Sjungma@eit.uni-kl.de.endif 40512027Sjungma@eit.uni-kl.de#endif 40612027Sjungma@eit.uni-kl.de 40712027Sjungma@eit.uni-kl.de 40812027Sjungma@eit.uni-kl.de 40912027Sjungma@eit.uni-kl.de/* Start a single argument thread using parameters preloaded in the stack 41012027Sjungma@eit.uni-kl.de * during thread initialization (see comments on stack initialization in the 41112027Sjungma@eit.uni-kl.de * heather file). 41212027Sjungma@eit.uni-kl.de * 41312027Sjungma@eit.uni-kl.de * Executes: 41412027Sjungma@eit.uni-kl.de * 41512027Sjungma@eit.uni-kl.de * only(u, t, userf); 41612027Sjungma@eit.uni-kl.de */ 41712027Sjungma@eit.uni-kl.de#if 0 41812027Sjungma@eit.uni-kl.de.if 0 41912027Sjungma@eit.uni-kl.de#endif 42012027Sjungma@eit.uni-kl.devoid qt_start(void); 42112027Sjungma@eit.uni-kl.deasm void qt_start(void) 42212027Sjungma@eit.uni-kl.de{ 42312027Sjungma@eit.uni-kl.de#if 0 42412027Sjungma@eit.uni-kl.de.endif 42512027Sjungma@eit.uni-kl.de#endif 42612027Sjungma@eit.uni-kl.de 42712027Sjungma@eit.uni-kl.de#if 0 42812027Sjungma@eit.uni-kl.deqt_start: 42912027Sjungma@eit.uni-kl.de_qt_start: 43012027Sjungma@eit.uni-kl.de#endif 43112027Sjungma@eit.uni-kl.de lwz %r3,PAR_0(%r1) /* "u" in r3 */ 43212027Sjungma@eit.uni-kl.de lwz %r4,PAR_1(%r1) /* "t" in r4 */ 43312027Sjungma@eit.uni-kl.de lwz %r5,PAR_2(%r1) /* "userf" in r5 */ 43412027Sjungma@eit.uni-kl.de lwz %r6,PAR_3(%r1) /* "only" in r6 */ 43512027Sjungma@eit.uni-kl.de mtlr %r6 /* "only" address in the link reg */ 43612027Sjungma@eit.uni-kl.de/* call only(u, t, userf) */ 43712027Sjungma@eit.uni-kl.de blrl /* jump to "only" */ 43812027Sjungma@eit.uni-kl.de/* error if it returns */ 43912027Sjungma@eit.uni-kl.de b qt_error 44012027Sjungma@eit.uni-kl.de/* dead code (some inline asm "wants" the epilog, or they genetare it) */ 44112027Sjungma@eit.uni-kl.de blr 44212027Sjungma@eit.uni-kl.de 44312027Sjungma@eit.uni-kl.de#if 0 44412027Sjungma@eit.uni-kl.de.if 0 44512027Sjungma@eit.uni-kl.de#endif 44612027Sjungma@eit.uni-kl.de} 44712027Sjungma@eit.uni-kl.de#if 0 44812027Sjungma@eit.uni-kl.de.endif 44912027Sjungma@eit.uni-kl.de#endif 45012027Sjungma@eit.uni-kl.de 45112027Sjungma@eit.uni-kl.de 45212027Sjungma@eit.uni-kl.de 45312027Sjungma@eit.uni-kl.de/* Start a variant argument thread using parameters preloaded in the stack 45412027Sjungma@eit.uni-kl.de * during thread initialization (see comments on stack initialization in the 45512027Sjungma@eit.uni-kl.de * heather file). 45612027Sjungma@eit.uni-kl.de * 45712027Sjungma@eit.uni-kl.de * Executes: 45812027Sjungma@eit.uni-kl.de * 45912027Sjungma@eit.uni-kl.de * startup(t); 46012027Sjungma@eit.uni-kl.de * userf_return = userf(...); 46112027Sjungma@eit.uni-kl.de * cleanup(pt, userf_return); 46212027Sjungma@eit.uni-kl.de * 46312027Sjungma@eit.uni-kl.de 46412027Sjungma@eit.uni-kl.de 46512027Sjungma@eit.uni-kl.de ***** Stack layout on start ***** 46612027Sjungma@eit.uni-kl.de 46712027Sjungma@eit.uni-kl.de 46812027Sjungma@eit.uni-kl.de backchain -> STACK BOTTOM (higher address) 46912027Sjungma@eit.uni-kl.de +==========================+ 47012027Sjungma@eit.uni-kl.de backchain - 4 -> | | 47112027Sjungma@eit.uni-kl.de + LOCAL VARIABLES AREA + 47212027Sjungma@eit.uni-kl.de .............. 47312027Sjungma@eit.uni-kl.de + + 47412027Sjungma@eit.uni-kl.de | | 47512027Sjungma@eit.uni-kl.de +--------------------------+ 47612027Sjungma@eit.uni-kl.de | | 47712027Sjungma@eit.uni-kl.de + ALIGNMEBNT PAD + 47812027Sjungma@eit.uni-kl.de .............. 47912027Sjungma@eit.uni-kl.de + (if needed) + 48012027Sjungma@eit.uni-kl.de | | 48112027Sjungma@eit.uni-kl.de +--------------------------+ 48212027Sjungma@eit.uni-kl.de | | arg(n) 48312027Sjungma@eit.uni-kl.de + + 48412027Sjungma@eit.uni-kl.de | | 48512027Sjungma@eit.uni-kl.de + VARIABLE ARGUMENT LIST + 48612027Sjungma@eit.uni-kl.de .............. 48712027Sjungma@eit.uni-kl.de + for userf call + 48812027Sjungma@eit.uni-kl.de SP + PAR(5) -> | | arg(1) 48912027Sjungma@eit.uni-kl.de + + 49012027Sjungma@eit.uni-kl.de SP + PAR(4) -> | | arg(0) 49112027Sjungma@eit.uni-kl.de +--------------------------+ 49212027Sjungma@eit.uni-kl.de SP + PAR(3) -> | | cleanup par 49312027Sjungma@eit.uni-kl.de + + 49412027Sjungma@eit.uni-kl.de SP + PAR(2) -> | | userf par 49512027Sjungma@eit.uni-kl.de + PARAMETER AREA + 49612027Sjungma@eit.uni-kl.de SP + PAR(1) -> | | startup par 49712027Sjungma@eit.uni-kl.de + + 49812027Sjungma@eit.uni-kl.de SP + PAR(0) -> | | t par 49912027Sjungma@eit.uni-kl.de +--------------------------+ 50012027Sjungma@eit.uni-kl.de | | 50112027Sjungma@eit.uni-kl.de + LINKAGE AREA + 50212027Sjungma@eit.uni-kl.de SP -> | | 50312027Sjungma@eit.uni-kl.de +==========================+ 50412027Sjungma@eit.uni-kl.de STACK TOP (lower address) 50512027Sjungma@eit.uni-kl.de 50612027Sjungma@eit.uni-kl.de Stack grows down 50712027Sjungma@eit.uni-kl.de | 50812027Sjungma@eit.uni-kl.de V 50912027Sjungma@eit.uni-kl.de 51012027Sjungma@eit.uni-kl.de 51112027Sjungma@eit.uni-kl.de 51212027Sjungma@eit.uni-kl.de ***** Stack layout before call userf ***** 51312027Sjungma@eit.uni-kl.de 51412027Sjungma@eit.uni-kl.de 51512027Sjungma@eit.uni-kl.de backchain -> STACK BOTTOM (higher address) 51612027Sjungma@eit.uni-kl.de +==========================+ 51712027Sjungma@eit.uni-kl.de backchain - 4 -> | | 51812027Sjungma@eit.uni-kl.de + LOCAL VARIABLES AREA + 51912027Sjungma@eit.uni-kl.de .............. 52012027Sjungma@eit.uni-kl.de + + 52112027Sjungma@eit.uni-kl.de | | 52212027Sjungma@eit.uni-kl.de +--------------------------+ 52312027Sjungma@eit.uni-kl.de | | 52412027Sjungma@eit.uni-kl.de + ALIGNMEBNT PAD + 52512027Sjungma@eit.uni-kl.de .............. 52612027Sjungma@eit.uni-kl.de + (if needed) + 52712027Sjungma@eit.uni-kl.de | | 52812027Sjungma@eit.uni-kl.de +--------------------------+ 52912027Sjungma@eit.uni-kl.de | | arg(n) 53012027Sjungma@eit.uni-kl.de + + 53112027Sjungma@eit.uni-kl.de | | 53212027Sjungma@eit.uni-kl.de + VARIABLE ARGUMENT LIST + 53312027Sjungma@eit.uni-kl.de .............. 53412027Sjungma@eit.uni-kl.de + for userf call + 53512027Sjungma@eit.uni-kl.de SP + PAR(1) -> | | arg(1) 53612027Sjungma@eit.uni-kl.de + + 53712027Sjungma@eit.uni-kl.de SP + PAR(0) -> | | arg(0) 53812027Sjungma@eit.uni-kl.de +--------------------------+ 53912027Sjungma@eit.uni-kl.de | | 54012027Sjungma@eit.uni-kl.de + LINKAGE AREA + 54112027Sjungma@eit.uni-kl.de SP -> | | 54212027Sjungma@eit.uni-kl.de +==========================+ 54312027Sjungma@eit.uni-kl.de STACK TOP (lower address) 54412027Sjungma@eit.uni-kl.de 54512027Sjungma@eit.uni-kl.de Stack grows down 54612027Sjungma@eit.uni-kl.de | 54712027Sjungma@eit.uni-kl.de V 54812027Sjungma@eit.uni-kl.de 54912027Sjungma@eit.uni-kl.de 55012027Sjungma@eit.uni-kl.de * To call "userf(...)", the argument list must be adiacent to the linkage 55112027Sjungma@eit.uni-kl.de * area. Instead of copy the argument list, we move back the linkage area 55212027Sjungma@eit.uni-kl.de * (actually, we just increase the SP and copy the backchain). "t" and 55312027Sjungma@eit.uni-kl.de * "cleanup" are saved in a local variable area in order to call 55412027Sjungma@eit.uni-kl.de * cleanup(pt, userf_return). 55512027Sjungma@eit.uni-kl.de 55612027Sjungma@eit.uni-kl.de*/ 55712027Sjungma@eit.uni-kl.de 55812027Sjungma@eit.uni-kl.de 55912027Sjungma@eit.uni-kl.de#if 0 56012027Sjungma@eit.uni-kl.de.if 0 56112027Sjungma@eit.uni-kl.de#endif 56212027Sjungma@eit.uni-kl.devoid qt_vstart(void); 56312027Sjungma@eit.uni-kl.deasm void qt_vstart(void) 56412027Sjungma@eit.uni-kl.de{ 56512027Sjungma@eit.uni-kl.de#if 0 56612027Sjungma@eit.uni-kl.de.endif 56712027Sjungma@eit.uni-kl.de#endif 56812027Sjungma@eit.uni-kl.de 56912027Sjungma@eit.uni-kl.de#if 0 57012027Sjungma@eit.uni-kl.deqt_vstart: 57112027Sjungma@eit.uni-kl.de_qt_vstart: 57212027Sjungma@eit.uni-kl.de#endif 57312027Sjungma@eit.uni-kl.de/* NOTICE: the callee routines could save parameter registers in the caller's 57412027Sjungma@eit.uni-kl.de * stack parameter area. We put "t" in PAR(0) in such a way, if startup(t) 57512027Sjungma@eit.uni-kl.de * will save "t", it will be saved on the same location thus not delething 57612027Sjungma@eit.uni-kl.de * any other parameter. 57712027Sjungma@eit.uni-kl.de */ 57812027Sjungma@eit.uni-kl.de 57912027Sjungma@eit.uni-kl.de/* since we will move back the linckage area (to make it adiacent to the 58012027Sjungma@eit.uni-kl.de * parameter list), we need to save "t" and "cleanup". We have made room for 58112027Sjungma@eit.uni-kl.de * this on the bottom of the stack frame. */ 58212027Sjungma@eit.uni-kl.de 58312027Sjungma@eit.uni-kl.de/* save parameters in the local variable area */ 58412027Sjungma@eit.uni-kl.de lwz %r11,0(%r1) /* get the backchain */ 58512027Sjungma@eit.uni-kl.de lwz %r3,P_T(%r1) 58612027Sjungma@eit.uni-kl.de lwz %r4,P_CLEANUP(%r1) 58712027Sjungma@eit.uni-kl.de stw %r3,P_T_SAVE(%r11) /* save "pt" */ 58812027Sjungma@eit.uni-kl.de stw %r4,P_CLEANUP_SAVE(%r11) /* save "cleanup" */ 58912027Sjungma@eit.uni-kl.de 59012027Sjungma@eit.uni-kl.de/* call startup(t) */ 59112027Sjungma@eit.uni-kl.de lwz %r5,P_STARTUP(%r1) 59212027Sjungma@eit.uni-kl.de mtlr %r5 59312027Sjungma@eit.uni-kl.de blrl /* call "startup" */ 59412027Sjungma@eit.uni-kl.de 59512027Sjungma@eit.uni-kl.de/* call userf(...) */ 59612027Sjungma@eit.uni-kl.de lwz %r11,0(%r1) /* reload backchain (r11 is volatile) */ 59712027Sjungma@eit.uni-kl.de lwz %r4,P_USERF(%r1) /* load "userf" */ 59812027Sjungma@eit.uni-kl.de mtlr %r4 59912027Sjungma@eit.uni-kl.de 60012027Sjungma@eit.uni-kl.de /* first eight parameter of the variant list must be copyed in 60112027Sjungma@eit.uni-kl.de * GPR3-GPR10. There is a four places offset due to "t", "startup", 60212027Sjungma@eit.uni-kl.de * userf" and "cleanup" */ 60312027Sjungma@eit.uni-kl.de 60412027Sjungma@eit.uni-kl.de lwz %r3,PAR_4(%r1) 60512027Sjungma@eit.uni-kl.de lwz %r4,PAR_5(%r1) 60612027Sjungma@eit.uni-kl.de lwz %r5,PAR_6(%r1) 60712027Sjungma@eit.uni-kl.de lwz %r6,PAR_7(%r1) 60812027Sjungma@eit.uni-kl.de lwz %r7,PAR_8(%r1) 60912027Sjungma@eit.uni-kl.de lwz %r8,PAR_9(%r1) 61012027Sjungma@eit.uni-kl.de lwz %r9,PAR_10(%r1) 61112027Sjungma@eit.uni-kl.de lwz %r10,PAR_11(%r1) 61212027Sjungma@eit.uni-kl.de 61312027Sjungma@eit.uni-kl.de 61412027Sjungma@eit.uni-kl.de /* move the linkage area to be adiacent to the argument list */ 61512027Sjungma@eit.uni-kl.de stw %r11,VARGS_BKOFF(%r1) /* copy backchain */ 61612027Sjungma@eit.uni-kl.de addi %r1,%r1,VARGS_BKOFF /* move back the stack */ 61712027Sjungma@eit.uni-kl.de 61812027Sjungma@eit.uni-kl.de blrl /* call "userf" */ 61912027Sjungma@eit.uni-kl.de 62012027Sjungma@eit.uni-kl.de/* call qt_cleanup(void *pt, void *vuserf_return) */ 62112027Sjungma@eit.uni-kl.de lwz %r11,0(%r1) /* reload backchain (r11 is volatile) */ 62212027Sjungma@eit.uni-kl.de 62312027Sjungma@eit.uni-kl.de mr %r4,%r3 /* push "userf" return as 2nd parameter */ 62412027Sjungma@eit.uni-kl.de lwz %r3,P_T_SAVE(%r11) /* reload "pt" */ 62512027Sjungma@eit.uni-kl.de lwz %r5,P_CLEANUP_SAVE(%r11) /* reload "cleanup" */ 62612027Sjungma@eit.uni-kl.de mtlr %r5 62712027Sjungma@eit.uni-kl.de blrl 62812027Sjungma@eit.uni-kl.de b qt_error 62912027Sjungma@eit.uni-kl.de/* dead code (some inline asm "wants" the epilog, or they genetare it) */ 63012027Sjungma@eit.uni-kl.de blr 63112027Sjungma@eit.uni-kl.de 63212027Sjungma@eit.uni-kl.de#if 0 63312027Sjungma@eit.uni-kl.de.if 0 63412027Sjungma@eit.uni-kl.de#endif 63512027Sjungma@eit.uni-kl.de} 63612027Sjungma@eit.uni-kl.de#if 0 63712027Sjungma@eit.uni-kl.de.endif 63812027Sjungma@eit.uni-kl.de#endif 63912027Sjungma@eit.uni-kl.de 640