9
9
"encoding/binary"
10
10
"fmt"
11
11
"io"
12
+ "math"
12
13
"strings"
13
14
)
14
15
@@ -37,7 +38,7 @@ func GoSyntax(inst Inst, pc uint64, symname func(uint64) (string, uint64), text
37
38
op := inst .Op .String ()
38
39
39
40
switch inst .Op &^ 15 {
40
- case LDR_EQ , LDRB_EQ , LDRH_EQ , LDRSB_EQ , LDRSH_EQ :
41
+ case LDR_EQ , LDRB_EQ , LDRH_EQ , LDRSB_EQ , LDRSH_EQ , VLDR_EQ :
41
42
// Check for RET
42
43
reg , _ := inst .Args [0 ].(Reg )
43
44
mem , _ := inst .Args [1 ].(Mem )
@@ -48,7 +49,7 @@ func GoSyntax(inst Inst, pc uint64, symname func(uint64) (string, uint64), text
48
49
// Check for PC-relative load.
49
50
if mem .Base == PC && mem .Sign == 0 && mem .Mode == AddrOffset && text != nil {
50
51
addr := uint32 (pc ) + 8 + uint32 (mem .Offset )
51
- buf := make ([]byte , 4 )
52
+ buf := make ([]byte , 8 )
52
53
switch inst .Op &^ 15 {
53
54
case LDRB_EQ , LDRSB_EQ :
54
55
if _ , err := text .ReadAt (buf [:1 ], int64 (addr )); err != nil {
@@ -63,7 +64,7 @@ func GoSyntax(inst Inst, pc uint64, symname func(uint64) (string, uint64), text
63
64
args [1 ] = fmt .Sprintf ("$%#x" , binary .LittleEndian .Uint16 (buf ))
64
65
65
66
case LDR_EQ :
66
- if _ , err := text .ReadAt (buf , int64 (addr )); err != nil {
67
+ if _ , err := text .ReadAt (buf [: 4 ] , int64 (addr )); err != nil {
67
68
break
68
69
}
69
70
x := binary .LittleEndian .Uint32 (buf )
@@ -72,14 +73,30 @@ func GoSyntax(inst Inst, pc uint64, symname func(uint64) (string, uint64), text
72
73
} else {
73
74
args [1 ] = fmt .Sprintf ("$%#x" , x )
74
75
}
76
+
77
+ case VLDR_EQ :
78
+ switch {
79
+ case strings .HasPrefix (args [0 ], "D" ): // VLDR.F64
80
+ if _ , err := text .ReadAt (buf , int64 (addr )); err != nil {
81
+ break
82
+ }
83
+ args [1 ] = fmt .Sprintf ("$%f" , math .Float64frombits (binary .LittleEndian .Uint64 (buf )))
84
+ case strings .HasPrefix (args [0 ], "S" ): // VLDR.F32
85
+ if _ , err := text .ReadAt (buf [:4 ], int64 (addr )); err != nil {
86
+ break
87
+ }
88
+ args [1 ] = fmt .Sprintf ("$%f" , math .Float32frombits (binary .LittleEndian .Uint32 (buf )))
89
+ default :
90
+ panic (fmt .Sprintf ("wrong FP register: %v" , inst ))
91
+ }
75
92
}
76
93
}
77
94
}
78
95
79
96
// Move addressing mode into opcode suffix.
80
97
suffix := ""
81
98
switch inst .Op &^ 15 {
82
- case LDR_EQ , LDRB_EQ , LDRSB_EQ , LDRH_EQ , LDRSH_EQ , STR_EQ , STRB_EQ , STRH_EQ :
99
+ case LDR_EQ , LDRB_EQ , LDRSB_EQ , LDRH_EQ , LDRSH_EQ , STR_EQ , STRB_EQ , STRH_EQ , VLDR_EQ , VSTR_EQ :
83
100
mem , _ := inst .Args [1 ].(Mem )
84
101
switch mem .Mode {
85
102
case AddrOffset , AddrLDM :
@@ -133,6 +150,19 @@ func GoSyntax(inst Inst, pc uint64, symname func(uint64) (string, uint64), text
133
150
op = "MOVHU" + op [4 :] + suffix
134
151
case LDRSH_EQ :
135
152
op = "MOVHS" + op [5 :] + suffix
153
+ case VLDR_EQ :
154
+ switch {
155
+ case strings .HasPrefix (args [1 ], "D" ): // VLDR.F64
156
+ op = "MOVD" + op [4 :] + suffix
157
+ args [1 ] = "F" + args [1 ][1 :] // Dx -> Fx
158
+ case strings .HasPrefix (args [1 ], "S" ): // VLDR.F32
159
+ op = "MOVF" + op [4 :] + suffix
160
+ if inst .Args [0 ].(Reg )& 1 == 0 { // Sx -> Fy, y = x/2, if x is even
161
+ args [1 ] = fmt .Sprintf ("F%d" , (inst .Args [0 ].(Reg )- S0 )/ 2 )
162
+ }
163
+ default :
164
+ panic (fmt .Sprintf ("wrong FP register: %v" , inst ))
165
+ }
136
166
137
167
case STR_EQ :
138
168
op = "MOVW" + op [3 :] + suffix
@@ -143,6 +173,20 @@ func GoSyntax(inst Inst, pc uint64, symname func(uint64) (string, uint64), text
143
173
case STRH_EQ :
144
174
op = "MOVH" + op [4 :] + suffix
145
175
args [0 ], args [1 ] = args [1 ], args [0 ]
176
+ case VSTR_EQ :
177
+ switch {
178
+ case strings .HasPrefix (args [1 ], "D" ): // VSTR.F64
179
+ op = "MOVD" + op [4 :] + suffix
180
+ args [1 ] = "F" + args [1 ][1 :] // Dx -> Fx
181
+ case strings .HasPrefix (args [1 ], "S" ): // VSTR.F32
182
+ op = "MOVF" + op [4 :] + suffix
183
+ if inst .Args [0 ].(Reg )& 1 == 0 { // Sx -> Fy, y = x/2, if x is even
184
+ args [1 ] = fmt .Sprintf ("F%d" , (inst .Args [0 ].(Reg )- S0 )/ 2 )
185
+ }
186
+ default :
187
+ panic (fmt .Sprintf ("wrong FP register: %v" , inst ))
188
+ }
189
+ args [0 ], args [1 ] = args [1 ], args [0 ]
146
190
}
147
191
148
192
if args != nil {
0 commit comments