Skip to content

Commit d676bd2

Browse files
authored
Merge pull request #130 from abner-chenc/master
loong64: implement buildJmpDirective function
2 parents 6a89ed8 + bfdbf60 commit d676bd2

File tree

2 files changed

+71
-0
lines changed

2 files changed

+71
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ gomonkey is a library to make monkey patching in unit tests easy, and the core i
2525
- amd64
2626
- arm64
2727
- 386
28+
- loong64
2829

2930
- OS
3031
- Linux

jmp_loong64.go

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

0 commit comments

Comments
 (0)