1*3cab2bb3Spatrick//===----------------------Hexagon builtin routine ------------------------===// 2*3cab2bb3Spatrick// 3*3cab2bb3Spatrick// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*3cab2bb3Spatrick// See https://llvm.org/LICENSE.txt for license information. 5*3cab2bb3Spatrick// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*3cab2bb3Spatrick// 7*3cab2bb3Spatrick//===----------------------------------------------------------------------===// 8*3cab2bb3Spatrick 9*3cab2bb3Spatrick// Functions that implement common sequences in function prologues and epilogues 10*3cab2bb3Spatrick// used to save code size 11*3cab2bb3Spatrick 12*3cab2bb3Spatrick .macro FUNCTION_BEGIN name 13*3cab2bb3Spatrick .p2align 2 14*3cab2bb3Spatrick .section .text.\name,"ax",@progbits 15*3cab2bb3Spatrick .globl \name 16*3cab2bb3Spatrick .type \name, @function 17*3cab2bb3Spatrick\name: 18*3cab2bb3Spatrick .endm 19*3cab2bb3Spatrick 20*3cab2bb3Spatrick .macro FUNCTION_END name 21*3cab2bb3Spatrick .size \name, . - \name 22*3cab2bb3Spatrick .endm 23*3cab2bb3Spatrick 24*3cab2bb3Spatrick .macro FALLTHROUGH_TAIL_CALL name0 name1 25*3cab2bb3Spatrick .p2align 2 26*3cab2bb3Spatrick .size \name0, . - \name0 27*3cab2bb3Spatrick .globl \name1 28*3cab2bb3Spatrick .type \name1, @function 29*3cab2bb3Spatrick\name1: 30*3cab2bb3Spatrick .endm 31*3cab2bb3Spatrick 32*3cab2bb3Spatrick 33*3cab2bb3Spatrick 34*3cab2bb3Spatrick 35*3cab2bb3Spatrick// Save r17:16 at fp+#-8, r19:18 at fp+#-16, r21:20 at fp+#-24, r23:22 at 36*3cab2bb3Spatrick// fp+#-32, r25:24 at fp+#-40, and r27:26 at fp+#-48. 37*3cab2bb3Spatrick// The compiler knows that the __save_* functions clobber LR. No other 38*3cab2bb3Spatrick// registers should be used without informing the compiler. 39*3cab2bb3Spatrick 40*3cab2bb3SpatrickFUNCTION_BEGIN __save_r16_through_r27 41*3cab2bb3Spatrick { 42*3cab2bb3Spatrick memd(fp+#-48) = r27:26 43*3cab2bb3Spatrick memd(fp+#-40) = r25:24 44*3cab2bb3Spatrick } 45*3cab2bb3Spatrick { 46*3cab2bb3Spatrick memd(fp+#-32) = r23:22 47*3cab2bb3Spatrick memd(fp+#-24) = r21:20 48*3cab2bb3Spatrick } 49*3cab2bb3Spatrick { 50*3cab2bb3Spatrick memd(fp+#-16) = r19:18 51*3cab2bb3Spatrick memd(fp+#-8) = r17:16 52*3cab2bb3Spatrick jumpr lr 53*3cab2bb3Spatrick } 54*3cab2bb3SpatrickFUNCTION_END __save_r16_through_r27 55*3cab2bb3Spatrick 56*3cab2bb3SpatrickFUNCTION_BEGIN __save_r16_through_r25 57*3cab2bb3Spatrick { 58*3cab2bb3Spatrick memd(fp+#-40) = r25:24 59*3cab2bb3Spatrick memd(fp+#-32) = r23:22 60*3cab2bb3Spatrick } 61*3cab2bb3Spatrick { 62*3cab2bb3Spatrick memd(fp+#-24) = r21:20 63*3cab2bb3Spatrick memd(fp+#-16) = r19:18 64*3cab2bb3Spatrick } 65*3cab2bb3Spatrick { 66*3cab2bb3Spatrick memd(fp+#-8) = r17:16 67*3cab2bb3Spatrick jumpr lr 68*3cab2bb3Spatrick } 69*3cab2bb3SpatrickFUNCTION_END __save_r16_through_r25 70*3cab2bb3Spatrick 71*3cab2bb3SpatrickFUNCTION_BEGIN __save_r16_through_r23 72*3cab2bb3Spatrick { 73*3cab2bb3Spatrick memd(fp+#-32) = r23:22 74*3cab2bb3Spatrick memd(fp+#-24) = r21:20 75*3cab2bb3Spatrick } 76*3cab2bb3Spatrick { 77*3cab2bb3Spatrick memd(fp+#-16) = r19:18 78*3cab2bb3Spatrick memd(fp+#-8) = r17:16 79*3cab2bb3Spatrick jumpr lr 80*3cab2bb3Spatrick } 81*3cab2bb3SpatrickFUNCTION_END __save_r16_through_r23 82*3cab2bb3Spatrick 83*3cab2bb3SpatrickFUNCTION_BEGIN __save_r16_through_r21 84*3cab2bb3Spatrick { 85*3cab2bb3Spatrick memd(fp+#-24) = r21:20 86*3cab2bb3Spatrick memd(fp+#-16) = r19:18 87*3cab2bb3Spatrick } 88*3cab2bb3Spatrick { 89*3cab2bb3Spatrick memd(fp+#-8) = r17:16 90*3cab2bb3Spatrick jumpr lr 91*3cab2bb3Spatrick } 92*3cab2bb3SpatrickFUNCTION_END __save_r16_through_r21 93*3cab2bb3Spatrick 94*3cab2bb3SpatrickFUNCTION_BEGIN __save_r16_through_r19 95*3cab2bb3Spatrick { 96*3cab2bb3Spatrick memd(fp+#-16) = r19:18 97*3cab2bb3Spatrick memd(fp+#-8) = r17:16 98*3cab2bb3Spatrick jumpr lr 99*3cab2bb3Spatrick } 100*3cab2bb3SpatrickFUNCTION_END __save_r16_through_r19 101*3cab2bb3Spatrick 102*3cab2bb3SpatrickFUNCTION_BEGIN __save_r16_through_r17 103*3cab2bb3Spatrick { 104*3cab2bb3Spatrick memd(fp+#-8) = r17:16 105*3cab2bb3Spatrick jumpr lr 106*3cab2bb3Spatrick } 107*3cab2bb3SpatrickFUNCTION_END __save_r16_through_r17 108*3cab2bb3Spatrick 109*3cab2bb3Spatrick// For each of the *_before_tailcall functions, jumpr lr is executed in parallel 110*3cab2bb3Spatrick// with deallocframe. That way, the return gets the old value of lr, which is 111*3cab2bb3Spatrick// where these functions need to return, and at the same time, lr gets the value 112*3cab2bb3Spatrick// it needs going into the tail call. 113*3cab2bb3Spatrick 114*3cab2bb3Spatrick 115*3cab2bb3SpatrickFUNCTION_BEGIN __restore_r16_through_r27_and_deallocframe_before_tailcall 116*3cab2bb3Spatrick r27:26 = memd(fp+#-48) 117*3cab2bb3Spatrick { 118*3cab2bb3Spatrick r25:24 = memd(fp+#-40) 119*3cab2bb3Spatrick r23:22 = memd(fp+#-32) 120*3cab2bb3Spatrick } 121*3cab2bb3Spatrick { 122*3cab2bb3Spatrick r21:20 = memd(fp+#-24) 123*3cab2bb3Spatrick r19:18 = memd(fp+#-16) 124*3cab2bb3Spatrick } 125*3cab2bb3Spatrick { 126*3cab2bb3Spatrick r17:16 = memd(fp+#-8) 127*3cab2bb3Spatrick deallocframe 128*3cab2bb3Spatrick jumpr lr 129*3cab2bb3Spatrick } 130*3cab2bb3SpatrickFUNCTION_END __restore_r16_through_r27_and_deallocframe_before_tailcall 131*3cab2bb3Spatrick 132*3cab2bb3SpatrickFUNCTION_BEGIN __restore_r16_through_r25_and_deallocframe_before_tailcall 133*3cab2bb3Spatrick { 134*3cab2bb3Spatrick r25:24 = memd(fp+#-40) 135*3cab2bb3Spatrick r23:22 = memd(fp+#-32) 136*3cab2bb3Spatrick } 137*3cab2bb3Spatrick { 138*3cab2bb3Spatrick r21:20 = memd(fp+#-24) 139*3cab2bb3Spatrick r19:18 = memd(fp+#-16) 140*3cab2bb3Spatrick } 141*3cab2bb3Spatrick { 142*3cab2bb3Spatrick r17:16 = memd(fp+#-8) 143*3cab2bb3Spatrick deallocframe 144*3cab2bb3Spatrick jumpr lr 145*3cab2bb3Spatrick } 146*3cab2bb3SpatrickFUNCTION_END __restore_r16_through_r25_and_deallocframe_before_tailcall 147*3cab2bb3Spatrick 148*3cab2bb3SpatrickFUNCTION_BEGIN __restore_r16_through_r23_and_deallocframe_before_tailcall 149*3cab2bb3Spatrick { 150*3cab2bb3Spatrick r23:22 = memd(fp+#-32) 151*3cab2bb3Spatrick r21:20 = memd(fp+#-24) 152*3cab2bb3Spatrick } 153*3cab2bb3Spatrick r19:18 = memd(fp+#-16) 154*3cab2bb3Spatrick { 155*3cab2bb3Spatrick r17:16 = memd(fp+#-8) 156*3cab2bb3Spatrick deallocframe 157*3cab2bb3Spatrick jumpr lr 158*3cab2bb3Spatrick } 159*3cab2bb3SpatrickFUNCTION_END __restore_r16_through_r23_and_deallocframe_before_tailcall 160*3cab2bb3Spatrick 161*3cab2bb3Spatrick 162*3cab2bb3SpatrickFUNCTION_BEGIN __restore_r16_through_r21_and_deallocframe_before_tailcall 163*3cab2bb3Spatrick { 164*3cab2bb3Spatrick r21:20 = memd(fp+#-24) 165*3cab2bb3Spatrick r19:18 = memd(fp+#-16) 166*3cab2bb3Spatrick } 167*3cab2bb3Spatrick { 168*3cab2bb3Spatrick r17:16 = memd(fp+#-8) 169*3cab2bb3Spatrick deallocframe 170*3cab2bb3Spatrick jumpr lr 171*3cab2bb3Spatrick } 172*3cab2bb3SpatrickFUNCTION_END __restore_r16_through_r19_and_deallocframe_before_tailcall 173*3cab2bb3Spatrick 174*3cab2bb3SpatrickFUNCTION_BEGIN __restore_r16_through_r19_and_deallocframe_before_tailcall 175*3cab2bb3Spatrick r19:18 = memd(fp+#-16) 176*3cab2bb3Spatrick { 177*3cab2bb3Spatrick r17:16 = memd(fp+#-8) 178*3cab2bb3Spatrick deallocframe 179*3cab2bb3Spatrick jumpr lr 180*3cab2bb3Spatrick } 181*3cab2bb3SpatrickFUNCTION_END __restore_r16_through_r19_and_deallocframe_before_tailcall 182*3cab2bb3Spatrick 183*3cab2bb3SpatrickFUNCTION_BEGIN __restore_r16_through_r17_and_deallocframe_before_tailcall 184*3cab2bb3Spatrick { 185*3cab2bb3Spatrick r17:16 = memd(fp+#-8) 186*3cab2bb3Spatrick deallocframe 187*3cab2bb3Spatrick jumpr lr 188*3cab2bb3Spatrick } 189*3cab2bb3SpatrickFUNCTION_END __restore_r16_through_r17_and_deallocframe_before_tailcall 190*3cab2bb3Spatrick 191*3cab2bb3Spatrick 192*3cab2bb3SpatrickFUNCTION_BEGIN __restore_r16_through_r27_and_deallocframe 193*3cab2bb3Spatrick r27:26 = memd(fp+#-48) 194*3cab2bb3Spatrick { 195*3cab2bb3Spatrick r25:24 = memd(fp+#-40) 196*3cab2bb3Spatrick r23:22 = memd(fp+#-32) 197*3cab2bb3Spatrick } 198*3cab2bb3Spatrick { 199*3cab2bb3Spatrick r21:20 = memd(fp+#-24) 200*3cab2bb3Spatrick r19:18 = memd(fp+#-16) 201*3cab2bb3Spatrick } 202*3cab2bb3Spatrick { 203*3cab2bb3Spatrick r17:16 = memd(fp+#-8) 204*3cab2bb3Spatrick dealloc_return 205*3cab2bb3Spatrick } 206*3cab2bb3SpatrickFUNCTION_END __restore_r16_through_r27_and_deallocframe 207*3cab2bb3Spatrick 208*3cab2bb3SpatrickFUNCTION_BEGIN __restore_r16_through_r25_and_deallocframe 209*3cab2bb3Spatrick { 210*3cab2bb3Spatrick r25:24 = memd(fp+#-40) 211*3cab2bb3Spatrick r23:22 = memd(fp+#-32) 212*3cab2bb3Spatrick } 213*3cab2bb3Spatrick { 214*3cab2bb3Spatrick r21:20 = memd(fp+#-24) 215*3cab2bb3Spatrick r19:18 = memd(fp+#-16) 216*3cab2bb3Spatrick } 217*3cab2bb3Spatrick { 218*3cab2bb3Spatrick r17:16 = memd(fp+#-8) 219*3cab2bb3Spatrick dealloc_return 220*3cab2bb3Spatrick } 221*3cab2bb3SpatrickFUNCTION_END __restore_r16_through_r25_and_deallocframe 222*3cab2bb3Spatrick 223*3cab2bb3SpatrickFUNCTION_BEGIN __restore_r16_through_r23_and_deallocframe 224*3cab2bb3Spatrick { 225*3cab2bb3Spatrick r23:22 = memd(fp+#-32) 226*3cab2bb3Spatrick } 227*3cab2bb3Spatrick { 228*3cab2bb3Spatrick r21:20 = memd(fp+#-24) 229*3cab2bb3Spatrick r19:18 = memd(fp+#-16) 230*3cab2bb3Spatrick } 231*3cab2bb3Spatrick { 232*3cab2bb3Spatrick r17:16 = memd(fp+#-8) 233*3cab2bb3Spatrick dealloc_return 234*3cab2bb3Spatrick } 235*3cab2bb3SpatrickFUNCTION_END __restore_r16_through_r23_and_deallocframe 236*3cab2bb3Spatrick 237*3cab2bb3SpatrickFUNCTION_BEGIN __restore_r16_through_r21_and_deallocframe 238*3cab2bb3Spatrick { 239*3cab2bb3Spatrick r21:20 = memd(fp+#-24) 240*3cab2bb3Spatrick r19:18 = memd(fp+#-16) 241*3cab2bb3Spatrick } 242*3cab2bb3Spatrick { 243*3cab2bb3Spatrick r17:16 = memd(fp+#-8) 244*3cab2bb3Spatrick dealloc_return 245*3cab2bb3Spatrick } 246*3cab2bb3SpatrickFUNCTION_END __restore_r16_through_r21_and_deallocframe 247*3cab2bb3Spatrick 248*3cab2bb3SpatrickFUNCTION_BEGIN __restore_r16_through_r19_and_deallocframe 249*3cab2bb3Spatrick { 250*3cab2bb3Spatrick r19:18 = memd(fp+#-16) 251*3cab2bb3Spatrick r17:16 = memd(fp+#-8) 252*3cab2bb3Spatrick } 253*3cab2bb3Spatrick { 254*3cab2bb3Spatrick dealloc_return 255*3cab2bb3Spatrick } 256*3cab2bb3SpatrickFUNCTION_END __restore_r16_through_r19_and_deallocframe 257*3cab2bb3Spatrick 258*3cab2bb3SpatrickFUNCTION_BEGIN __restore_r16_through_r17_and_deallocframe 259*3cab2bb3Spatrick { 260*3cab2bb3Spatrick r17:16 = memd(fp+#-8) 261*3cab2bb3Spatrick dealloc_return 262*3cab2bb3Spatrick } 263*3cab2bb3SpatrickFUNCTION_END __restore_r16_through_r17_and_deallocframe 264*3cab2bb3Spatrick 265*3cab2bb3SpatrickFUNCTION_BEGIN __deallocframe 266*3cab2bb3Spatrick dealloc_return 267*3cab2bb3SpatrickFUNCTION_END __deallocframe 268