1
2
3
4
5
6
7
8
9 package arch
10
11 import (
12 "cmd/internal/obj"
13 "cmd/internal/obj/loong64"
14 "errors"
15 "fmt"
16 )
17
18 func jumpLoong64(word string) bool {
19 switch word {
20 case "BEQ", "BFPF", "BFPT", "BLTZ", "BGEZ", "BLEZ", "BGTZ", "BLT", "BLTU", "JIRL", "BNE", "BGE", "BGEU", "JMP", "JAL", "CALL":
21 return true
22 }
23 return false
24 }
25
26
27
28
29 func IsLoong64RDTIME(op obj.As) bool {
30 switch op {
31 case loong64.ARDTIMELW, loong64.ARDTIMEHW, loong64.ARDTIMED:
32 return true
33 }
34 return false
35 }
36
37 func IsLoong64PRELD(op obj.As) bool {
38 switch op {
39 case loong64.APRELD, loong64.APRELDX:
40 return true
41 }
42 return false
43 }
44
45 func IsLoong64AMO(op obj.As) bool {
46 return loong64.IsAtomicInst(op)
47 }
48
49 var loong64ElemExtMap = map[string]int16{
50 "B": loong64.ARNG_B,
51 "H": loong64.ARNG_H,
52 "W": loong64.ARNG_W,
53 "V": loong64.ARNG_V,
54 "BU": loong64.ARNG_BU,
55 "HU": loong64.ARNG_HU,
56 "WU": loong64.ARNG_WU,
57 "VU": loong64.ARNG_VU,
58 }
59
60 var loong64LsxArngExtMap = map[string]int16{
61 "B16": loong64.ARNG_16B,
62 "H8": loong64.ARNG_8H,
63 "W4": loong64.ARNG_4W,
64 "V2": loong64.ARNG_2V,
65 }
66
67 var loong64LasxArngExtMap = map[string]int16{
68 "B32": loong64.ARNG_32B,
69 "H16": loong64.ARNG_16H,
70 "W8": loong64.ARNG_8W,
71 "V4": loong64.ARNG_4V,
72 "Q2": loong64.ARNG_2Q,
73 }
74
75
76 func Loong64RegisterExtension(a *obj.Addr, ext string, reg, num int16, isAmount, isIndex bool) error {
77 var ok bool
78 var arngType int16
79 var simdType int16
80 var simdReg int16
81
82 switch {
83 case reg >= loong64.REG_V0 && reg <= loong64.REG_V31:
84 simdType = loong64.LSX
85 simdReg = reg - loong64.REG_V0
86 case reg >= loong64.REG_X0 && reg <= loong64.REG_X31:
87 simdType = loong64.LASX
88 simdReg = reg - loong64.REG_X0
89 default:
90 return errors.New("Loong64 extension: invalid LSX/LASX register: " + fmt.Sprintf("%d", reg))
91 }
92
93 if isIndex {
94 arngType, ok = loong64ElemExtMap[ext]
95 if !ok {
96 return errors.New("Loong64 extension: invalid LSX/LASX arrangement type: " + ext)
97 }
98
99 a.Reg = loong64.REG_ELEM
100 a.Reg += ((simdReg & loong64.EXT_REG_MASK) << loong64.EXT_REG_SHIFT)
101 a.Reg += ((arngType & loong64.EXT_TYPE_MASK) << loong64.EXT_TYPE_SHIFT)
102 a.Reg += ((simdType & loong64.EXT_SIMDTYPE_MASK) << loong64.EXT_SIMDTYPE_SHIFT)
103 a.Index = num
104 } else {
105 switch simdType {
106 case loong64.LSX:
107 arngType, ok = loong64LsxArngExtMap[ext]
108 if !ok {
109 return errors.New("Loong64 extension: invalid LSX arrangement type: " + ext)
110 }
111
112 case loong64.LASX:
113 arngType, ok = loong64LasxArngExtMap[ext]
114 if !ok {
115 return errors.New("Loong64 extension: invalid LASX arrangement type: " + ext)
116 }
117 }
118
119 a.Reg = loong64.REG_ARNG
120 a.Reg += ((simdReg & loong64.EXT_REG_MASK) << loong64.EXT_REG_SHIFT)
121 a.Reg += ((arngType & loong64.EXT_TYPE_MASK) << loong64.EXT_TYPE_SHIFT)
122 a.Reg += ((simdType & loong64.EXT_SIMDTYPE_MASK) << loong64.EXT_SIMDTYPE_SHIFT)
123 }
124
125 return nil
126 }
127
128 func loong64RegisterNumber(name string, n int16) (int16, bool) {
129 switch name {
130 case "F":
131 if 0 <= n && n <= 31 {
132 return loong64.REG_F0 + n, true
133 }
134 case "FCSR":
135 if 0 <= n && n <= 31 {
136 return loong64.REG_FCSR0 + n, true
137 }
138 case "FCC":
139 if 0 <= n && n <= 31 {
140 return loong64.REG_FCC0 + n, true
141 }
142 case "R":
143 if 0 <= n && n <= 31 {
144 return loong64.REG_R0 + n, true
145 }
146 case "V":
147 if 0 <= n && n <= 31 {
148 return loong64.REG_V0 + n, true
149 }
150 case "X":
151 if 0 <= n && n <= 31 {
152 return loong64.REG_X0 + n, true
153 }
154 }
155 return 0, false
156 }
157
View as plain text