github.com/agiledragon/gomonkey/v2@v2.11.1-0.20240427155748-d56c6823ec17/jmp_loong64.go (about) 1 //go:build loong64 2 // +build loong64 3 4 package gomonkey 5 6 import "unsafe" 7 8 const ( 9 REG_R0 uint32 = 0 10 REG_R29 = 29 11 REG_R30 = 30 12 ) 13 14 const ( 15 OP_ORI uint32 = 0x00E << 22 16 OP_LU12IW = 0x00A << 25 17 OP_LU32ID = 0x00B << 25 18 OP_LU52ID = 0x00C << 22 19 OP_LDD = 0x0A3 << 22 20 OP_JIRL = 0x013 << 26 21 ) 22 23 func buildJmpDirective(double uintptr) []byte { 24 res := make([]byte, 0, 24) 25 26 bit11_0 := (double >> 0) & 0xFFF 27 bit31_12 := (double >> 12) & 0xFFFFF 28 bit51_32 := (double >> 32) & 0xFFFFF 29 bit63_52 := (double >> 52) & 0xFFF 30 31 // lu12i.w r29, bit31_12 32 // ori r29, r29, bit11_0 33 // lu32i.d r29, bit51_32 34 // lu52i.d r29, bit63_52 35 // ld.d, r30, r29, 0 36 // jirl r0, r30, 0 37 res = append(res, wireup_opc(OP_LU12IW, REG_R29, 0, bit31_12)...) 38 res = append(res, wireup_opc(OP_ORI, REG_R29, REG_R29, bit11_0)...) 39 res = append(res, wireup_opc(OP_LU32ID, REG_R29, 0, bit51_32)...) 40 res = append(res, wireup_opc(OP_LU52ID, REG_R29, REG_R29, bit63_52)...) 41 res = append(res, wireup_opc(OP_LDD, REG_R30, REG_R29, 0)...) 42 res = append(res, wireup_opc(OP_JIRL, REG_R0, REG_R30, 0)...) 43 44 return res 45 } 46 47 func wireup_opc(opc uint32, rd, rj uint32, val uintptr) []byte { 48 var m uint32 = 0 49 50 switch opc { 51 case OP_ORI, OP_LU52ID, OP_LDD: 52 m |= opc 53 m |= (rd & 0x1F) << 0 // rd 54 m |= (rj & 0x1F) << 5 // rj 55 m |= (uint32(val) & 0xFFF) << 10 // si12 56 57 case OP_LU12IW, OP_LU32ID: 58 m |= opc 59 m |= (rd & 0x1F) << 0 // rd 60 m |= (uint32(val) & 0xFFFFF) << 5 // si20 61 62 case OP_JIRL: 63 m |= opc 64 m |= (rd & 0x1F) << 0 // rd 65 m |= (rj & 0x1F) << 5 // rj 66 m |= (uint32(val) & 0xFFFF) << 10 // si16 67 } 68 69 res := make([]byte, 4) 70 *(*uint32)(unsafe.Pointer(&res[0])) = m 71 72 return res 73 }