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 func IsLoong64MUL(op obj.As) bool {
29 switch op {
30 case loong64.AMUL, loong64.AMULU, loong64.AMULV, loong64.AMULVU,
31 loong64.ADIV, loong64.ADIVU, loong64.ADIVV, loong64.ADIVVU,
32 loong64.AREM, loong64.AREMU, loong64.AREMV, loong64.AREMVU:
33 return true
34 }
35 return false
36 }
37
38
39
40
41 func IsLoong64RDTIME(op obj.As) bool {
42 switch op {
43 case loong64.ARDTIMELW, loong64.ARDTIMEHW, loong64.ARDTIMED:
44 return true
45 }
46 return false
47 }
48
49 func IsLoong64AMO(op obj.As) bool {
50 return loong64.IsAtomicInst(op)
51 }
52
53 var loong64ElemExtMap = map[string]int16{
54 "B": loong64.ARNG_B,
55 "H": loong64.ARNG_H,
56 "W": loong64.ARNG_W,
57 "V": loong64.ARNG_V,
58 "BU": loong64.ARNG_BU,
59 "HU": loong64.ARNG_HU,
60 "WU": loong64.ARNG_WU,
61 "VU": loong64.ARNG_VU,
62 }
63
64 var loong64LsxArngExtMap = map[string]int16{
65 "B16": loong64.ARNG_16B,
66 "H8": loong64.ARNG_8H,
67 "W4": loong64.ARNG_4W,
68 "V2": loong64.ARNG_2V,
69 }
70
71 var loong64LasxArngExtMap = map[string]int16{
72 "B32": loong64.ARNG_32B,
73 "H16": loong64.ARNG_16H,
74 "W8": loong64.ARNG_8W,
75 "V4": loong64.ARNG_4V,
76 "Q2": loong64.ARNG_2Q,
77 }
78
79
80 func Loong64RegisterExtension(a *obj.Addr, ext string, reg, num int16, isAmount, isIndex bool) error {
81 var ok bool
82 var arng_type int16
83 var simd_type int16
84
85 switch {
86 case reg >= loong64.REG_V0 && reg <= loong64.REG_V31:
87 simd_type = loong64.LSX
88 case reg >= loong64.REG_X0 && reg <= loong64.REG_X31:
89 simd_type = loong64.LASX
90 default:
91 return errors.New("Loong64 extension: invalid LSX/LASX register: " + fmt.Sprintf("%d", reg))
92 }
93
94 if isIndex {
95 arng_type, ok = loong64ElemExtMap[ext]
96 if !ok {
97 return errors.New("Loong64 extension: invalid LSX/LASX arrangement type: " + ext)
98 }
99
100 a.Reg = loong64.REG_ELEM
101 a.Reg += ((reg & loong64.EXT_REG_MASK) << loong64.EXT_REG_SHIFT)
102 a.Reg += ((arng_type & loong64.EXT_TYPE_MASK) << loong64.EXT_TYPE_SHIFT)
103 a.Reg += ((simd_type & loong64.EXT_SIMDTYPE_MASK) << loong64.EXT_SIMDTYPE_SHIFT)
104 a.Index = num
105 } else {
106 switch simd_type {
107 case loong64.LSX:
108 arng_type, ok = loong64LsxArngExtMap[ext]
109 if !ok {
110 return errors.New("Loong64 extension: invalid LSX arrangement type: " + ext)
111 }
112
113 case loong64.LASX:
114 arng_type, ok = loong64LasxArngExtMap[ext]
115 if !ok {
116 return errors.New("Loong64 extension: invalid LASX arrangement type: " + ext)
117 }
118 }
119
120 a.Reg = loong64.REG_ARNG
121 a.Reg += ((reg & loong64.EXT_REG_MASK) << loong64.EXT_REG_SHIFT)
122 a.Reg += ((arng_type & loong64.EXT_TYPE_MASK) << loong64.EXT_TYPE_SHIFT)
123 a.Reg += ((simd_type & loong64.EXT_SIMDTYPE_MASK) << loong64.EXT_SIMDTYPE_SHIFT)
124 }
125
126 return nil
127 }
128
129 func loong64RegisterNumber(name string, n int16) (int16, bool) {
130 switch name {
131 case "F":
132 if 0 <= n && n <= 31 {
133 return loong64.REG_F0 + n, true
134 }
135 case "FCSR":
136 if 0 <= n && n <= 31 {
137 return loong64.REG_FCSR0 + n, true
138 }
139 case "FCC":
140 if 0 <= n && n <= 31 {
141 return loong64.REG_FCC0 + n, true
142 }
143 case "R":
144 if 0 <= n && n <= 31 {
145 return loong64.REG_R0 + n, true
146 }
147 case "V":
148 if 0 <= n && n <= 31 {
149 return loong64.REG_V0 + n, true
150 }
151 case "X":
152 if 0 <= n && n <= 31 {
153 return loong64.REG_X0 + n, true
154 }
155 }
156 return 0, false
157 }
158
View as plain text