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 arng_type int16
79 var simd_type int16
80
81 switch {
82 case reg >= loong64.REG_V0 && reg <= loong64.REG_V31:
83 simd_type = loong64.LSX
84 case reg >= loong64.REG_X0 && reg <= loong64.REG_X31:
85 simd_type = loong64.LASX
86 default:
87 return errors.New("Loong64 extension: invalid LSX/LASX register: " + fmt.Sprintf("%d", reg))
88 }
89
90 if isIndex {
91 arng_type, ok = loong64ElemExtMap[ext]
92 if !ok {
93 return errors.New("Loong64 extension: invalid LSX/LASX arrangement type: " + ext)
94 }
95
96 a.Reg = loong64.REG_ELEM
97 a.Reg += ((reg & loong64.EXT_REG_MASK) << loong64.EXT_REG_SHIFT)
98 a.Reg += ((arng_type & loong64.EXT_TYPE_MASK) << loong64.EXT_TYPE_SHIFT)
99 a.Reg += ((simd_type & loong64.EXT_SIMDTYPE_MASK) << loong64.EXT_SIMDTYPE_SHIFT)
100 a.Index = num
101 } else {
102 switch simd_type {
103 case loong64.LSX:
104 arng_type, ok = loong64LsxArngExtMap[ext]
105 if !ok {
106 return errors.New("Loong64 extension: invalid LSX arrangement type: " + ext)
107 }
108
109 case loong64.LASX:
110 arng_type, ok = loong64LasxArngExtMap[ext]
111 if !ok {
112 return errors.New("Loong64 extension: invalid LASX arrangement type: " + ext)
113 }
114 }
115
116 a.Reg = loong64.REG_ARNG
117 a.Reg += ((reg & loong64.EXT_REG_MASK) << loong64.EXT_REG_SHIFT)
118 a.Reg += ((arng_type & loong64.EXT_TYPE_MASK) << loong64.EXT_TYPE_SHIFT)
119 a.Reg += ((simd_type & loong64.EXT_SIMDTYPE_MASK) << loong64.EXT_SIMDTYPE_SHIFT)
120 }
121
122 return nil
123 }
124
125 func loong64RegisterNumber(name string, n int16) (int16, bool) {
126 switch name {
127 case "F":
128 if 0 <= n && n <= 31 {
129 return loong64.REG_F0 + n, true
130 }
131 case "FCSR":
132 if 0 <= n && n <= 31 {
133 return loong64.REG_FCSR0 + n, true
134 }
135 case "FCC":
136 if 0 <= n && n <= 31 {
137 return loong64.REG_FCC0 + n, true
138 }
139 case "R":
140 if 0 <= n && n <= 31 {
141 return loong64.REG_R0 + n, true
142 }
143 case "V":
144 if 0 <= n && n <= 31 {
145 return loong64.REG_V0 + n, true
146 }
147 case "X":
148 if 0 <= n && n <= 31 {
149 return loong64.REG_X0 + n, true
150 }
151 }
152 return 0, false
153 }
154
View as plain text