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