1.text 2.macro do_call fn 3#ifdef _TMS320C6400_PLUS 4 callp .s2 (\fn), B3 5#elif defined(_TMS320C6400) 6 call .s2 (\fn) 7 addkpc .s2 9f, B3, 0 8 nop 4 99f: 10#else 11 call .s2 (\fn) 12 mhkl .s2 9f, B3 13 mhkh .s2 9f, B3 14 nop 3 159f: 16#endif 17.endm 18.align 2 19.global restore_core_regs 20.type restore_core_regs, STT_FUNC 21restore_core_regs: 22 mv .s2x A4, B4 23 ldw .d1t1 *+A4[0], A0 24 || ldw .d2t2 *++B4[16], B0 25 ldw .d1t1 *+A4[1], A1 26 || ldw .d2t2 *+B4[1], B1 27 ldw .d1t1 *+A4[2], A2 28 || ldw .d2t2 *+B4[2], B2 29 ldw .d1t1 *+A4[3], A3 30 || ldw .d2t2 *+B4[3], B3 31 ;; Base registers are loaded later 32 ldw .d1t1 *+A4[5], A5 33 || ldw .d2t2 *+B4[5], B5 34 ldw .d1t1 *+A4[6], A6 35 || ldw .d2t2 *+B4[6], B6 36 ldw .d1t1 *+A4[7], A7 37 || ldw .d2t2 *+B4[7], B7 38 ldw .d1t1 *+A4[8], A8 39 || ldw .d2t2 *+B4[8], B8 40 ldw .d1t1 *+A4[9], A9 41 || ldw .d2t2 *+B4[9], B9 42 ;; load PC into B10 so that it is ready for the branch 43 ldw .d2t2 *+B4[16], B10 44 ldw .d1t1 *+A4[11], A11 45 || ldw .d2t2 *+B4[11], B11 46 ldw .d1t1 *+A4[12], A12 47 || ldw .d2t2 *+B4[12], B12 48 ldw .d1t1 *+A4[13], A13 49 || ldw .d2t2 *+B4[13], B13 50 ldw .d1t1 *+A4[14], A14 51 || ldw .d2t2 *+B4[14], B14 52 ;; Loads have 4 delay slots. Take advantage of this to restore the 53 ;; scratch registers and stack pointer before the base registers 54 ;; disappear. We also need to make sure no interrupts occur, 55 ;; so put the whole thing in the delay slots of a dummy branch 56 ;; We can not move the ret earlier as that would cause it to occur 57 ;; before the last load completes 58 b .s1 (1f) 59 ldw .d1t1 *+A4[4], A4 60 || ldw .d2t2 *+B4[4], B4 61 ldw .d1t1 *+A4[15], A15 62 || ldw .d2t2 *+B4[15], B15 63 ret .s2 B10 64 ldw .d1t1 *+A4[10], A10 65 || ldw .d2t2 *+B4[10], B10 66 nop 1 671: 68 nop 3 69.size restore_core_regs, . - restore_core_regs 70 71.macro UNWIND_WRAPPER name argreg argside 72.global \name 73.type \name, STT_FUNC 74\name: 75 # Create saved register state: flags,A0-A15,B0-B15,PC = 136 bytes. 76 # Plus 4 (rounded to 8) for saving return. 77 addk .s2 -144, B15 78 stw .d2t1 A0, *+B15[2] 79 stw .d2t1 A1, *+B15[3] 80 stw .d2t1 A2, *+B15[4] 81 stw .d2t1 A3, *+B15[5] 82 stw .d2t1 A4, *+B15[6] 83 stw .d2t1 A5, *+B15[7] 84 stw .d2t1 A6, *+B15[8] 85 stw .d2t1 A7, *+B15[9] 86 stw .d2t1 A8, *+B15[10] 87 stw .d2t1 A9, *+B15[11] 88 stw .d2t1 A10, *+B15[12] 89 stw .d2t1 A11, *+B15[13] 90 stw .d2t1 A12, *+B15[14] 91 stw .d2t1 A13, *+B15[15] 92 stw .d2t1 A14, *+B15[16] 93 stw .d2t1 A15, *+B15[17] 94 mv .s1x B15, A0 95 addk .s1 144, A0 96 stw .d2t2 B0, *+B15[18] 97 stw .d2t2 B1, *+B15[19] 98 stw .d2t2 B2, *+B15[20] 99 stw .d2t2 B3, *+B15[21] 100 stw .d2t2 B4, *+B15[22] 101 stw .d2t2 B5, *+B15[23] 102 stw .d2t2 B6, *+B15[24] 103 stw .d2t2 B7, *+B15[25] 104 stw .d2t2 B8, *+B15[26] 105 stw .d2t2 B9, *+B15[27] 106 stw .d2t2 B10, *+B15[28] 107 stw .d2t2 B11, *+B15[29] 108 stw .d2t2 B12, *+B15[30] 109 stw .d2t2 B13, *+B15[31] 110 stw .d2t2 B14, *+B15[32] 111 stw .d2t1 A0, *+B15[33] 112 stw .d2t1 A0, *+B15[34] 113 # Zero demand saved flags 114 mvk .s1 0, A0 115 stw .d2t1 A0, *+B15[1] 116 # Save return address, setup additional argument and call function 117 stw .d2t2 B3, *+B15[35] 118 add .d\argside B15, 4, \argreg 119 do_call __gnu\name 120 # Restore stack and return 121 ldw .d2t2 *+B15[35], B3 122 addk .s2 144, B15 123 nop 3 124 ret .s2 B3 125 nop 5 126.size \name, . - \name 127.endm 128 129UNWIND_WRAPPER _Unwind_RaiseException B4 2 130UNWIND_WRAPPER _Unwind_Resume B4 2 131UNWIND_WRAPPER _Unwind_Resume_or_Rethrow B4 2 132UNWIND_WRAPPER _Unwind_ForcedUnwind B6 2 133UNWIND_WRAPPER _Unwind_Backtrace A6 1x 134