xref: /aosp_15_r20/external/vixl/src/aarch32/operands-aarch32.cc (revision f5c631da2f1efdd72b5fd1e20510e4042af13d77)
1*f5c631daSSadaf Ebrahimi // Copyright 2017, VIXL authors
2*f5c631daSSadaf Ebrahimi // All rights reserved.
3*f5c631daSSadaf Ebrahimi //
4*f5c631daSSadaf Ebrahimi // Redistribution and use in source and binary forms, with or without
5*f5c631daSSadaf Ebrahimi // modification, are permitted provided that the following conditions are met:
6*f5c631daSSadaf Ebrahimi //
7*f5c631daSSadaf Ebrahimi //   * Redistributions of source code must retain the above copyright notice,
8*f5c631daSSadaf Ebrahimi //     this list of conditions and the following disclaimer.
9*f5c631daSSadaf Ebrahimi //   * Redistributions in binary form must reproduce the above copyright
10*f5c631daSSadaf Ebrahimi //     notice, this list of conditions and the following disclaimer in the
11*f5c631daSSadaf Ebrahimi //     documentation and/or other materials provided with the distribution.
12*f5c631daSSadaf Ebrahimi //   * Neither the name of ARM Limited nor the names of its contributors may
13*f5c631daSSadaf Ebrahimi //     be used to endorse or promote products derived from this software
14*f5c631daSSadaf Ebrahimi //     without specific prior written permission.
15*f5c631daSSadaf Ebrahimi //
16*f5c631daSSadaf Ebrahimi // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND
17*f5c631daSSadaf Ebrahimi // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18*f5c631daSSadaf Ebrahimi // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19*f5c631daSSadaf Ebrahimi // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
20*f5c631daSSadaf Ebrahimi // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21*f5c631daSSadaf Ebrahimi // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22*f5c631daSSadaf Ebrahimi // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23*f5c631daSSadaf Ebrahimi // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24*f5c631daSSadaf Ebrahimi // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25*f5c631daSSadaf Ebrahimi // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26*f5c631daSSadaf Ebrahimi // POSSIBILITY OF SUCH DAMAGE.
27*f5c631daSSadaf Ebrahimi 
28*f5c631daSSadaf Ebrahimi extern "C" {
29*f5c631daSSadaf Ebrahimi #include <inttypes.h>
30*f5c631daSSadaf Ebrahimi #include <stdint.h>
31*f5c631daSSadaf Ebrahimi }
32*f5c631daSSadaf Ebrahimi 
33*f5c631daSSadaf Ebrahimi #include <cassert>
34*f5c631daSSadaf Ebrahimi #include <cmath>
35*f5c631daSSadaf Ebrahimi #include <cstdio>
36*f5c631daSSadaf Ebrahimi #include <cstdlib>
37*f5c631daSSadaf Ebrahimi #include <cstring>
38*f5c631daSSadaf Ebrahimi #include <iomanip>
39*f5c631daSSadaf Ebrahimi #include <iostream>
40*f5c631daSSadaf Ebrahimi 
41*f5c631daSSadaf Ebrahimi #include "utils-vixl.h"
42*f5c631daSSadaf Ebrahimi #include "aarch32/constants-aarch32.h"
43*f5c631daSSadaf Ebrahimi #include "aarch32/instructions-aarch32.h"
44*f5c631daSSadaf Ebrahimi #include "aarch32/operands-aarch32.h"
45*f5c631daSSadaf Ebrahimi 
46*f5c631daSSadaf Ebrahimi namespace vixl {
47*f5c631daSSadaf Ebrahimi namespace aarch32 {
48*f5c631daSSadaf Ebrahimi 
49*f5c631daSSadaf Ebrahimi // Operand
50*f5c631daSSadaf Ebrahimi 
operator <<(std::ostream & os,const Operand & operand)51*f5c631daSSadaf Ebrahimi std::ostream& operator<<(std::ostream& os, const Operand& operand) {
52*f5c631daSSadaf Ebrahimi   if (operand.IsImmediate()) {
53*f5c631daSSadaf Ebrahimi     return os << "#" << operand.GetImmediate();
54*f5c631daSSadaf Ebrahimi   }
55*f5c631daSSadaf Ebrahimi   if (operand.IsImmediateShiftedRegister()) {
56*f5c631daSSadaf Ebrahimi     if ((operand.GetShift().IsLSL() || operand.GetShift().IsROR()) &&
57*f5c631daSSadaf Ebrahimi         (operand.GetShiftAmount() == 0)) {
58*f5c631daSSadaf Ebrahimi       return os << operand.GetBaseRegister();
59*f5c631daSSadaf Ebrahimi     }
60*f5c631daSSadaf Ebrahimi     if (operand.GetShift().IsRRX()) {
61*f5c631daSSadaf Ebrahimi       return os << operand.GetBaseRegister() << ", rrx";
62*f5c631daSSadaf Ebrahimi     }
63*f5c631daSSadaf Ebrahimi     return os << operand.GetBaseRegister() << ", " << operand.GetShift() << " #"
64*f5c631daSSadaf Ebrahimi               << operand.GetShiftAmount();
65*f5c631daSSadaf Ebrahimi   }
66*f5c631daSSadaf Ebrahimi   if (operand.IsRegisterShiftedRegister()) {
67*f5c631daSSadaf Ebrahimi     return os << operand.GetBaseRegister() << ", " << operand.GetShift() << " "
68*f5c631daSSadaf Ebrahimi               << operand.GetShiftRegister();
69*f5c631daSSadaf Ebrahimi   }
70*f5c631daSSadaf Ebrahimi   VIXL_UNREACHABLE();
71*f5c631daSSadaf Ebrahimi   return os;
72*f5c631daSSadaf Ebrahimi }
73*f5c631daSSadaf Ebrahimi 
operator <<(std::ostream & os,const NeonImmediate & neon_imm)74*f5c631daSSadaf Ebrahimi std::ostream& operator<<(std::ostream& os, const NeonImmediate& neon_imm) {
75*f5c631daSSadaf Ebrahimi   if (neon_imm.IsDouble()) {
76*f5c631daSSadaf Ebrahimi     if (neon_imm.imm_.d_ == 0) {
77*f5c631daSSadaf Ebrahimi       if (copysign(1.0, neon_imm.imm_.d_) < 0.0) {
78*f5c631daSSadaf Ebrahimi         return os << "#-0.0";
79*f5c631daSSadaf Ebrahimi       }
80*f5c631daSSadaf Ebrahimi       return os << "#0.0";
81*f5c631daSSadaf Ebrahimi     }
82*f5c631daSSadaf Ebrahimi     return os << "#" << std::setprecision(9) << neon_imm.imm_.d_;
83*f5c631daSSadaf Ebrahimi   }
84*f5c631daSSadaf Ebrahimi   if (neon_imm.IsFloat()) {
85*f5c631daSSadaf Ebrahimi     if (neon_imm.imm_.f_ == 0) {
86*f5c631daSSadaf Ebrahimi       if (copysign(1.0, neon_imm.imm_.d_) < 0.0) return os << "#-0.0";
87*f5c631daSSadaf Ebrahimi       return os << "#0.0";
88*f5c631daSSadaf Ebrahimi     }
89*f5c631daSSadaf Ebrahimi     return os << "#" << std::setprecision(9) << neon_imm.imm_.f_;
90*f5c631daSSadaf Ebrahimi   }
91*f5c631daSSadaf Ebrahimi   if (neon_imm.IsInteger64()) {
92*f5c631daSSadaf Ebrahimi     return os << "#0x" << std::hex << std::setw(16) << std::setfill('0')
93*f5c631daSSadaf Ebrahimi               << neon_imm.imm_.u64_ << std::dec;
94*f5c631daSSadaf Ebrahimi   }
95*f5c631daSSadaf Ebrahimi   return os << "#" << neon_imm.imm_.u32_;
96*f5c631daSSadaf Ebrahimi }
97*f5c631daSSadaf Ebrahimi 
98*f5c631daSSadaf Ebrahimi // SOperand
99*f5c631daSSadaf Ebrahimi 
operator <<(std::ostream & os,const SOperand & operand)100*f5c631daSSadaf Ebrahimi std::ostream& operator<<(std::ostream& os, const SOperand& operand) {
101*f5c631daSSadaf Ebrahimi   if (operand.IsImmediate()) {
102*f5c631daSSadaf Ebrahimi     return os << operand.GetNeonImmediate();
103*f5c631daSSadaf Ebrahimi   }
104*f5c631daSSadaf Ebrahimi   return os << operand.GetRegister();
105*f5c631daSSadaf Ebrahimi }
106*f5c631daSSadaf Ebrahimi 
107*f5c631daSSadaf Ebrahimi // DOperand
108*f5c631daSSadaf Ebrahimi 
operator <<(std::ostream & os,const DOperand & operand)109*f5c631daSSadaf Ebrahimi std::ostream& operator<<(std::ostream& os, const DOperand& operand) {
110*f5c631daSSadaf Ebrahimi   if (operand.IsImmediate()) {
111*f5c631daSSadaf Ebrahimi     return os << operand.GetNeonImmediate();
112*f5c631daSSadaf Ebrahimi   }
113*f5c631daSSadaf Ebrahimi   return os << operand.GetRegister();
114*f5c631daSSadaf Ebrahimi }
115*f5c631daSSadaf Ebrahimi 
116*f5c631daSSadaf Ebrahimi // QOperand
117*f5c631daSSadaf Ebrahimi 
operator <<(std::ostream & os,const QOperand & operand)118*f5c631daSSadaf Ebrahimi std::ostream& operator<<(std::ostream& os, const QOperand& operand) {
119*f5c631daSSadaf Ebrahimi   if (operand.IsImmediate()) {
120*f5c631daSSadaf Ebrahimi     return os << operand.GetNeonImmediate();
121*f5c631daSSadaf Ebrahimi   }
122*f5c631daSSadaf Ebrahimi   return os << operand.GetRegister();
123*f5c631daSSadaf Ebrahimi }
124*f5c631daSSadaf Ebrahimi 
125*f5c631daSSadaf Ebrahimi 
ImmediateVbic(DataType dt,const NeonImmediate & neon_imm)126*f5c631daSSadaf Ebrahimi ImmediateVbic::ImmediateVbic(DataType dt, const NeonImmediate& neon_imm) {
127*f5c631daSSadaf Ebrahimi   if (neon_imm.IsInteger32()) {
128*f5c631daSSadaf Ebrahimi     uint32_t immediate = neon_imm.GetImmediate<uint32_t>();
129*f5c631daSSadaf Ebrahimi     if (dt.GetValue() == I16) {
130*f5c631daSSadaf Ebrahimi       if ((immediate & ~0xff) == 0) {
131*f5c631daSSadaf Ebrahimi         SetEncodingValue(0x9);
132*f5c631daSSadaf Ebrahimi         SetEncodedImmediate(immediate);
133*f5c631daSSadaf Ebrahimi       } else if ((immediate & ~0xff00) == 0) {
134*f5c631daSSadaf Ebrahimi         SetEncodingValue(0xb);
135*f5c631daSSadaf Ebrahimi         SetEncodedImmediate(immediate >> 8);
136*f5c631daSSadaf Ebrahimi       }
137*f5c631daSSadaf Ebrahimi     } else if (dt.GetValue() == I32) {
138*f5c631daSSadaf Ebrahimi       if ((immediate & ~0xff) == 0) {
139*f5c631daSSadaf Ebrahimi         SetEncodingValue(0x1);
140*f5c631daSSadaf Ebrahimi         SetEncodedImmediate(immediate);
141*f5c631daSSadaf Ebrahimi       } else if ((immediate & ~0xff00) == 0) {
142*f5c631daSSadaf Ebrahimi         SetEncodingValue(0x3);
143*f5c631daSSadaf Ebrahimi         SetEncodedImmediate(immediate >> 8);
144*f5c631daSSadaf Ebrahimi       } else if ((immediate & ~0xff0000) == 0) {
145*f5c631daSSadaf Ebrahimi         SetEncodingValue(0x5);
146*f5c631daSSadaf Ebrahimi         SetEncodedImmediate(immediate >> 16);
147*f5c631daSSadaf Ebrahimi       } else if ((immediate & ~0xff000000) == 0) {
148*f5c631daSSadaf Ebrahimi         SetEncodingValue(0x7);
149*f5c631daSSadaf Ebrahimi         SetEncodedImmediate(immediate >> 24);
150*f5c631daSSadaf Ebrahimi       }
151*f5c631daSSadaf Ebrahimi     }
152*f5c631daSSadaf Ebrahimi   }
153*f5c631daSSadaf Ebrahimi }
154*f5c631daSSadaf Ebrahimi 
155*f5c631daSSadaf Ebrahimi 
DecodeDt(uint32_t cmode)156*f5c631daSSadaf Ebrahimi DataType ImmediateVbic::DecodeDt(uint32_t cmode) {
157*f5c631daSSadaf Ebrahimi   switch (cmode) {
158*f5c631daSSadaf Ebrahimi     case 0x1:
159*f5c631daSSadaf Ebrahimi     case 0x3:
160*f5c631daSSadaf Ebrahimi     case 0x5:
161*f5c631daSSadaf Ebrahimi     case 0x7:
162*f5c631daSSadaf Ebrahimi       return I32;
163*f5c631daSSadaf Ebrahimi     case 0x9:
164*f5c631daSSadaf Ebrahimi     case 0xb:
165*f5c631daSSadaf Ebrahimi       return I16;
166*f5c631daSSadaf Ebrahimi     default:
167*f5c631daSSadaf Ebrahimi       break;
168*f5c631daSSadaf Ebrahimi   }
169*f5c631daSSadaf Ebrahimi   VIXL_UNREACHABLE();
170*f5c631daSSadaf Ebrahimi   return kDataTypeValueInvalid;
171*f5c631daSSadaf Ebrahimi }
172*f5c631daSSadaf Ebrahimi 
173*f5c631daSSadaf Ebrahimi 
DecodeImmediate(uint32_t cmode,uint32_t immediate)174*f5c631daSSadaf Ebrahimi NeonImmediate ImmediateVbic::DecodeImmediate(uint32_t cmode,
175*f5c631daSSadaf Ebrahimi                                              uint32_t immediate) {
176*f5c631daSSadaf Ebrahimi   switch (cmode) {
177*f5c631daSSadaf Ebrahimi     case 0x1:
178*f5c631daSSadaf Ebrahimi     case 0x9:
179*f5c631daSSadaf Ebrahimi       return immediate;
180*f5c631daSSadaf Ebrahimi     case 0x3:
181*f5c631daSSadaf Ebrahimi     case 0xb:
182*f5c631daSSadaf Ebrahimi       return immediate << 8;
183*f5c631daSSadaf Ebrahimi     case 0x5:
184*f5c631daSSadaf Ebrahimi       return immediate << 16;
185*f5c631daSSadaf Ebrahimi     case 0x7:
186*f5c631daSSadaf Ebrahimi       return immediate << 24;
187*f5c631daSSadaf Ebrahimi     default:
188*f5c631daSSadaf Ebrahimi       break;
189*f5c631daSSadaf Ebrahimi   }
190*f5c631daSSadaf Ebrahimi   VIXL_UNREACHABLE();
191*f5c631daSSadaf Ebrahimi   return 0;
192*f5c631daSSadaf Ebrahimi }
193*f5c631daSSadaf Ebrahimi 
194*f5c631daSSadaf Ebrahimi 
ImmediateVmov(DataType dt,const NeonImmediate & neon_imm)195*f5c631daSSadaf Ebrahimi ImmediateVmov::ImmediateVmov(DataType dt, const NeonImmediate& neon_imm) {
196*f5c631daSSadaf Ebrahimi   if (neon_imm.IsInteger()) {
197*f5c631daSSadaf Ebrahimi     switch (dt.GetValue()) {
198*f5c631daSSadaf Ebrahimi       case I8:
199*f5c631daSSadaf Ebrahimi         if (neon_imm.CanConvert<uint8_t>()) {
200*f5c631daSSadaf Ebrahimi           SetEncodingValue(0xe);
201*f5c631daSSadaf Ebrahimi           SetEncodedImmediate(neon_imm.GetImmediate<uint8_t>());
202*f5c631daSSadaf Ebrahimi         }
203*f5c631daSSadaf Ebrahimi         break;
204*f5c631daSSadaf Ebrahimi       case I16:
205*f5c631daSSadaf Ebrahimi         if (neon_imm.IsInteger32()) {
206*f5c631daSSadaf Ebrahimi           uint32_t immediate = neon_imm.GetImmediate<uint32_t>();
207*f5c631daSSadaf Ebrahimi           if ((immediate & ~0xff) == 0) {
208*f5c631daSSadaf Ebrahimi             SetEncodingValue(0x8);
209*f5c631daSSadaf Ebrahimi             SetEncodedImmediate(immediate);
210*f5c631daSSadaf Ebrahimi           } else if ((immediate & ~0xff00) == 0) {
211*f5c631daSSadaf Ebrahimi             SetEncodingValue(0xa);
212*f5c631daSSadaf Ebrahimi             SetEncodedImmediate(immediate >> 8);
213*f5c631daSSadaf Ebrahimi           }
214*f5c631daSSadaf Ebrahimi         }
215*f5c631daSSadaf Ebrahimi         break;
216*f5c631daSSadaf Ebrahimi       case I32:
217*f5c631daSSadaf Ebrahimi         if (neon_imm.IsInteger32()) {
218*f5c631daSSadaf Ebrahimi           uint32_t immediate = neon_imm.GetImmediate<uint32_t>();
219*f5c631daSSadaf Ebrahimi           if ((immediate & ~0xff) == 0) {
220*f5c631daSSadaf Ebrahimi             SetEncodingValue(0x0);
221*f5c631daSSadaf Ebrahimi             SetEncodedImmediate(immediate);
222*f5c631daSSadaf Ebrahimi           } else if ((immediate & ~0xff00) == 0) {
223*f5c631daSSadaf Ebrahimi             SetEncodingValue(0x2);
224*f5c631daSSadaf Ebrahimi             SetEncodedImmediate(immediate >> 8);
225*f5c631daSSadaf Ebrahimi           } else if ((immediate & ~0xff0000) == 0) {
226*f5c631daSSadaf Ebrahimi             SetEncodingValue(0x4);
227*f5c631daSSadaf Ebrahimi             SetEncodedImmediate(immediate >> 16);
228*f5c631daSSadaf Ebrahimi           } else if ((immediate & ~0xff000000) == 0) {
229*f5c631daSSadaf Ebrahimi             SetEncodingValue(0x6);
230*f5c631daSSadaf Ebrahimi             SetEncodedImmediate(immediate >> 24);
231*f5c631daSSadaf Ebrahimi           } else if ((immediate & ~0xff00) == 0xff) {
232*f5c631daSSadaf Ebrahimi             SetEncodingValue(0xc);
233*f5c631daSSadaf Ebrahimi             SetEncodedImmediate(immediate >> 8);
234*f5c631daSSadaf Ebrahimi           } else if ((immediate & ~0xff0000) == 0xffff) {
235*f5c631daSSadaf Ebrahimi             SetEncodingValue(0xd);
236*f5c631daSSadaf Ebrahimi             SetEncodedImmediate(immediate >> 16);
237*f5c631daSSadaf Ebrahimi           }
238*f5c631daSSadaf Ebrahimi         }
239*f5c631daSSadaf Ebrahimi         break;
240*f5c631daSSadaf Ebrahimi       case I64: {
241*f5c631daSSadaf Ebrahimi         bool is_valid = true;
242*f5c631daSSadaf Ebrahimi         uint32_t encoding = 0;
243*f5c631daSSadaf Ebrahimi         if (neon_imm.IsInteger32()) {
244*f5c631daSSadaf Ebrahimi           uint32_t immediate = neon_imm.GetImmediate<uint32_t>();
245*f5c631daSSadaf Ebrahimi           uint32_t mask = 0xff000000;
246*f5c631daSSadaf Ebrahimi           for (uint32_t set_bit = 1 << 3; set_bit != 0; set_bit >>= 1) {
247*f5c631daSSadaf Ebrahimi             if ((immediate & mask) == mask) {
248*f5c631daSSadaf Ebrahimi               encoding |= set_bit;
249*f5c631daSSadaf Ebrahimi             } else if ((immediate & mask) != 0) {
250*f5c631daSSadaf Ebrahimi               is_valid = false;
251*f5c631daSSadaf Ebrahimi               break;
252*f5c631daSSadaf Ebrahimi             }
253*f5c631daSSadaf Ebrahimi             mask >>= 8;
254*f5c631daSSadaf Ebrahimi           }
255*f5c631daSSadaf Ebrahimi         } else {
256*f5c631daSSadaf Ebrahimi           uint64_t immediate = neon_imm.GetImmediate<uint64_t>();
257*f5c631daSSadaf Ebrahimi           uint64_t mask = UINT64_C(0xff) << 56;
258*f5c631daSSadaf Ebrahimi           for (uint32_t set_bit = 1 << 7; set_bit != 0; set_bit >>= 1) {
259*f5c631daSSadaf Ebrahimi             if ((immediate & mask) == mask) {
260*f5c631daSSadaf Ebrahimi               encoding |= set_bit;
261*f5c631daSSadaf Ebrahimi             } else if ((immediate & mask) != 0) {
262*f5c631daSSadaf Ebrahimi               is_valid = false;
263*f5c631daSSadaf Ebrahimi               break;
264*f5c631daSSadaf Ebrahimi             }
265*f5c631daSSadaf Ebrahimi             mask >>= 8;
266*f5c631daSSadaf Ebrahimi           }
267*f5c631daSSadaf Ebrahimi         }
268*f5c631daSSadaf Ebrahimi         if (is_valid) {
269*f5c631daSSadaf Ebrahimi           SetEncodingValue(0x1e);
270*f5c631daSSadaf Ebrahimi           SetEncodedImmediate(encoding);
271*f5c631daSSadaf Ebrahimi         }
272*f5c631daSSadaf Ebrahimi         break;
273*f5c631daSSadaf Ebrahimi       }
274*f5c631daSSadaf Ebrahimi       default:
275*f5c631daSSadaf Ebrahimi         break;
276*f5c631daSSadaf Ebrahimi     }
277*f5c631daSSadaf Ebrahimi   } else {
278*f5c631daSSadaf Ebrahimi     switch (dt.GetValue()) {
279*f5c631daSSadaf Ebrahimi       case F32:
280*f5c631daSSadaf Ebrahimi         if (neon_imm.IsFloat() || neon_imm.IsDouble()) {
281*f5c631daSSadaf Ebrahimi           ImmediateVFP vfp(neon_imm.GetImmediate<float>());
282*f5c631daSSadaf Ebrahimi           if (vfp.IsValid()) {
283*f5c631daSSadaf Ebrahimi             SetEncodingValue(0xf);
284*f5c631daSSadaf Ebrahimi             SetEncodedImmediate(vfp.GetEncodingValue());
285*f5c631daSSadaf Ebrahimi           }
286*f5c631daSSadaf Ebrahimi         }
287*f5c631daSSadaf Ebrahimi         break;
288*f5c631daSSadaf Ebrahimi       default:
289*f5c631daSSadaf Ebrahimi         break;
290*f5c631daSSadaf Ebrahimi     }
291*f5c631daSSadaf Ebrahimi   }
292*f5c631daSSadaf Ebrahimi }
293*f5c631daSSadaf Ebrahimi 
294*f5c631daSSadaf Ebrahimi 
DecodeDt(uint32_t cmode)295*f5c631daSSadaf Ebrahimi DataType ImmediateVmov::DecodeDt(uint32_t cmode) {
296*f5c631daSSadaf Ebrahimi   switch (cmode & 0xf) {
297*f5c631daSSadaf Ebrahimi     case 0x0:
298*f5c631daSSadaf Ebrahimi     case 0x2:
299*f5c631daSSadaf Ebrahimi     case 0x4:
300*f5c631daSSadaf Ebrahimi     case 0x6:
301*f5c631daSSadaf Ebrahimi     case 0xc:
302*f5c631daSSadaf Ebrahimi     case 0xd:
303*f5c631daSSadaf Ebrahimi       return I32;
304*f5c631daSSadaf Ebrahimi     case 0x8:
305*f5c631daSSadaf Ebrahimi     case 0xa:
306*f5c631daSSadaf Ebrahimi       return I16;
307*f5c631daSSadaf Ebrahimi     case 0xe:
308*f5c631daSSadaf Ebrahimi       return ((cmode & 0x10) == 0) ? I8 : I64;
309*f5c631daSSadaf Ebrahimi     case 0xf:
310*f5c631daSSadaf Ebrahimi       if ((cmode & 0x10) == 0) return F32;
311*f5c631daSSadaf Ebrahimi       break;
312*f5c631daSSadaf Ebrahimi     default:
313*f5c631daSSadaf Ebrahimi       break;
314*f5c631daSSadaf Ebrahimi   }
315*f5c631daSSadaf Ebrahimi   VIXL_UNREACHABLE();
316*f5c631daSSadaf Ebrahimi   return kDataTypeValueInvalid;
317*f5c631daSSadaf Ebrahimi }
318*f5c631daSSadaf Ebrahimi 
319*f5c631daSSadaf Ebrahimi 
DecodeImmediate(uint32_t cmode,uint32_t immediate)320*f5c631daSSadaf Ebrahimi NeonImmediate ImmediateVmov::DecodeImmediate(uint32_t cmode,
321*f5c631daSSadaf Ebrahimi                                              uint32_t immediate) {
322*f5c631daSSadaf Ebrahimi   switch (cmode & 0xf) {
323*f5c631daSSadaf Ebrahimi     case 0x8:
324*f5c631daSSadaf Ebrahimi     case 0x0:
325*f5c631daSSadaf Ebrahimi       return immediate;
326*f5c631daSSadaf Ebrahimi     case 0x2:
327*f5c631daSSadaf Ebrahimi     case 0xa:
328*f5c631daSSadaf Ebrahimi       return immediate << 8;
329*f5c631daSSadaf Ebrahimi     case 0x4:
330*f5c631daSSadaf Ebrahimi       return immediate << 16;
331*f5c631daSSadaf Ebrahimi     case 0x6:
332*f5c631daSSadaf Ebrahimi       return immediate << 24;
333*f5c631daSSadaf Ebrahimi     case 0xc:
334*f5c631daSSadaf Ebrahimi       return (immediate << 8) | 0xff;
335*f5c631daSSadaf Ebrahimi     case 0xd:
336*f5c631daSSadaf Ebrahimi       return (immediate << 16) | 0xffff;
337*f5c631daSSadaf Ebrahimi     case 0xe: {
338*f5c631daSSadaf Ebrahimi       if (cmode == 0x1e) {
339*f5c631daSSadaf Ebrahimi         uint64_t encoding = 0;
340*f5c631daSSadaf Ebrahimi         for (uint32_t set_bit = 1 << 7; set_bit != 0; set_bit >>= 1) {
341*f5c631daSSadaf Ebrahimi           encoding <<= 8;
342*f5c631daSSadaf Ebrahimi           if ((immediate & set_bit) != 0) {
343*f5c631daSSadaf Ebrahimi             encoding |= 0xff;
344*f5c631daSSadaf Ebrahimi           }
345*f5c631daSSadaf Ebrahimi         }
346*f5c631daSSadaf Ebrahimi         return encoding;
347*f5c631daSSadaf Ebrahimi       } else {
348*f5c631daSSadaf Ebrahimi         return immediate;
349*f5c631daSSadaf Ebrahimi       }
350*f5c631daSSadaf Ebrahimi     }
351*f5c631daSSadaf Ebrahimi     case 0xf: {
352*f5c631daSSadaf Ebrahimi       return ImmediateVFP::Decode<float>(immediate);
353*f5c631daSSadaf Ebrahimi     }
354*f5c631daSSadaf Ebrahimi     default:
355*f5c631daSSadaf Ebrahimi       break;
356*f5c631daSSadaf Ebrahimi   }
357*f5c631daSSadaf Ebrahimi   VIXL_UNREACHABLE();
358*f5c631daSSadaf Ebrahimi   return 0;
359*f5c631daSSadaf Ebrahimi }
360*f5c631daSSadaf Ebrahimi 
361*f5c631daSSadaf Ebrahimi 
ImmediateVmvn(DataType dt,const NeonImmediate & neon_imm)362*f5c631daSSadaf Ebrahimi ImmediateVmvn::ImmediateVmvn(DataType dt, const NeonImmediate& neon_imm) {
363*f5c631daSSadaf Ebrahimi   if (neon_imm.IsInteger32()) {
364*f5c631daSSadaf Ebrahimi     uint32_t immediate = neon_imm.GetImmediate<uint32_t>();
365*f5c631daSSadaf Ebrahimi     switch (dt.GetValue()) {
366*f5c631daSSadaf Ebrahimi       case I16:
367*f5c631daSSadaf Ebrahimi         if ((immediate & ~0xff) == 0) {
368*f5c631daSSadaf Ebrahimi           SetEncodingValue(0x8);
369*f5c631daSSadaf Ebrahimi           SetEncodedImmediate(immediate);
370*f5c631daSSadaf Ebrahimi         } else if ((immediate & ~0xff00) == 0) {
371*f5c631daSSadaf Ebrahimi           SetEncodingValue(0xa);
372*f5c631daSSadaf Ebrahimi           SetEncodedImmediate(immediate >> 8);
373*f5c631daSSadaf Ebrahimi         }
374*f5c631daSSadaf Ebrahimi         break;
375*f5c631daSSadaf Ebrahimi       case I32:
376*f5c631daSSadaf Ebrahimi         if ((immediate & ~0xff) == 0) {
377*f5c631daSSadaf Ebrahimi           SetEncodingValue(0x0);
378*f5c631daSSadaf Ebrahimi           SetEncodedImmediate(immediate);
379*f5c631daSSadaf Ebrahimi         } else if ((immediate & ~0xff00) == 0) {
380*f5c631daSSadaf Ebrahimi           SetEncodingValue(0x2);
381*f5c631daSSadaf Ebrahimi           SetEncodedImmediate(immediate >> 8);
382*f5c631daSSadaf Ebrahimi         } else if ((immediate & ~0xff0000) == 0) {
383*f5c631daSSadaf Ebrahimi           SetEncodingValue(0x4);
384*f5c631daSSadaf Ebrahimi           SetEncodedImmediate(immediate >> 16);
385*f5c631daSSadaf Ebrahimi         } else if ((immediate & ~0xff000000) == 0) {
386*f5c631daSSadaf Ebrahimi           SetEncodingValue(0x6);
387*f5c631daSSadaf Ebrahimi           SetEncodedImmediate(immediate >> 24);
388*f5c631daSSadaf Ebrahimi         } else if ((immediate & ~0xff00) == 0xff) {
389*f5c631daSSadaf Ebrahimi           SetEncodingValue(0xc);
390*f5c631daSSadaf Ebrahimi           SetEncodedImmediate(immediate >> 8);
391*f5c631daSSadaf Ebrahimi         } else if ((immediate & ~0xff0000) == 0xffff) {
392*f5c631daSSadaf Ebrahimi           SetEncodingValue(0xd);
393*f5c631daSSadaf Ebrahimi           SetEncodedImmediate(immediate >> 16);
394*f5c631daSSadaf Ebrahimi         }
395*f5c631daSSadaf Ebrahimi         break;
396*f5c631daSSadaf Ebrahimi       default:
397*f5c631daSSadaf Ebrahimi         break;
398*f5c631daSSadaf Ebrahimi     }
399*f5c631daSSadaf Ebrahimi   }
400*f5c631daSSadaf Ebrahimi }
401*f5c631daSSadaf Ebrahimi 
402*f5c631daSSadaf Ebrahimi 
DecodeDt(uint32_t cmode)403*f5c631daSSadaf Ebrahimi DataType ImmediateVmvn::DecodeDt(uint32_t cmode) {
404*f5c631daSSadaf Ebrahimi   switch (cmode) {
405*f5c631daSSadaf Ebrahimi     case 0x0:
406*f5c631daSSadaf Ebrahimi     case 0x2:
407*f5c631daSSadaf Ebrahimi     case 0x4:
408*f5c631daSSadaf Ebrahimi     case 0x6:
409*f5c631daSSadaf Ebrahimi     case 0xc:
410*f5c631daSSadaf Ebrahimi     case 0xd:
411*f5c631daSSadaf Ebrahimi       return I32;
412*f5c631daSSadaf Ebrahimi     case 0x8:
413*f5c631daSSadaf Ebrahimi     case 0xa:
414*f5c631daSSadaf Ebrahimi       return I16;
415*f5c631daSSadaf Ebrahimi     default:
416*f5c631daSSadaf Ebrahimi       break;
417*f5c631daSSadaf Ebrahimi   }
418*f5c631daSSadaf Ebrahimi   VIXL_UNREACHABLE();
419*f5c631daSSadaf Ebrahimi   return kDataTypeValueInvalid;
420*f5c631daSSadaf Ebrahimi }
421*f5c631daSSadaf Ebrahimi 
422*f5c631daSSadaf Ebrahimi 
DecodeImmediate(uint32_t cmode,uint32_t immediate)423*f5c631daSSadaf Ebrahimi NeonImmediate ImmediateVmvn::DecodeImmediate(uint32_t cmode,
424*f5c631daSSadaf Ebrahimi                                              uint32_t immediate) {
425*f5c631daSSadaf Ebrahimi   switch (cmode) {
426*f5c631daSSadaf Ebrahimi     case 0x0:
427*f5c631daSSadaf Ebrahimi     case 0x8:
428*f5c631daSSadaf Ebrahimi       return immediate;
429*f5c631daSSadaf Ebrahimi     case 0x2:
430*f5c631daSSadaf Ebrahimi     case 0xa:
431*f5c631daSSadaf Ebrahimi       return immediate << 8;
432*f5c631daSSadaf Ebrahimi     case 0x4:
433*f5c631daSSadaf Ebrahimi       return immediate << 16;
434*f5c631daSSadaf Ebrahimi     case 0x6:
435*f5c631daSSadaf Ebrahimi       return immediate << 24;
436*f5c631daSSadaf Ebrahimi     case 0xc:
437*f5c631daSSadaf Ebrahimi       return (immediate << 8) | 0xff;
438*f5c631daSSadaf Ebrahimi     case 0xd:
439*f5c631daSSadaf Ebrahimi       return (immediate << 16) | 0xffff;
440*f5c631daSSadaf Ebrahimi     default:
441*f5c631daSSadaf Ebrahimi       break;
442*f5c631daSSadaf Ebrahimi   }
443*f5c631daSSadaf Ebrahimi   VIXL_UNREACHABLE();
444*f5c631daSSadaf Ebrahimi   return 0;
445*f5c631daSSadaf Ebrahimi }
446*f5c631daSSadaf Ebrahimi 
447*f5c631daSSadaf Ebrahimi 
ImmediateVorr(DataType dt,const NeonImmediate & neon_imm)448*f5c631daSSadaf Ebrahimi ImmediateVorr::ImmediateVorr(DataType dt, const NeonImmediate& neon_imm) {
449*f5c631daSSadaf Ebrahimi   if (neon_imm.IsInteger32()) {
450*f5c631daSSadaf Ebrahimi     uint32_t immediate = neon_imm.GetImmediate<uint32_t>();
451*f5c631daSSadaf Ebrahimi     if (dt.GetValue() == I16) {
452*f5c631daSSadaf Ebrahimi       if ((immediate & ~0xff) == 0) {
453*f5c631daSSadaf Ebrahimi         SetEncodingValue(0x9);
454*f5c631daSSadaf Ebrahimi         SetEncodedImmediate(immediate);
455*f5c631daSSadaf Ebrahimi       } else if ((immediate & ~0xff00) == 0) {
456*f5c631daSSadaf Ebrahimi         SetEncodingValue(0xb);
457*f5c631daSSadaf Ebrahimi         SetEncodedImmediate(immediate >> 8);
458*f5c631daSSadaf Ebrahimi       }
459*f5c631daSSadaf Ebrahimi     } else if (dt.GetValue() == I32) {
460*f5c631daSSadaf Ebrahimi       if ((immediate & ~0xff) == 0) {
461*f5c631daSSadaf Ebrahimi         SetEncodingValue(0x1);
462*f5c631daSSadaf Ebrahimi         SetEncodedImmediate(immediate);
463*f5c631daSSadaf Ebrahimi       } else if ((immediate & ~0xff00) == 0) {
464*f5c631daSSadaf Ebrahimi         SetEncodingValue(0x3);
465*f5c631daSSadaf Ebrahimi         SetEncodedImmediate(immediate >> 8);
466*f5c631daSSadaf Ebrahimi       } else if ((immediate & ~0xff0000) == 0) {
467*f5c631daSSadaf Ebrahimi         SetEncodingValue(0x5);
468*f5c631daSSadaf Ebrahimi         SetEncodedImmediate(immediate >> 16);
469*f5c631daSSadaf Ebrahimi       } else if ((immediate & ~0xff000000) == 0) {
470*f5c631daSSadaf Ebrahimi         SetEncodingValue(0x7);
471*f5c631daSSadaf Ebrahimi         SetEncodedImmediate(immediate >> 24);
472*f5c631daSSadaf Ebrahimi       }
473*f5c631daSSadaf Ebrahimi     }
474*f5c631daSSadaf Ebrahimi   }
475*f5c631daSSadaf Ebrahimi }
476*f5c631daSSadaf Ebrahimi 
477*f5c631daSSadaf Ebrahimi 
DecodeDt(uint32_t cmode)478*f5c631daSSadaf Ebrahimi DataType ImmediateVorr::DecodeDt(uint32_t cmode) {
479*f5c631daSSadaf Ebrahimi   switch (cmode) {
480*f5c631daSSadaf Ebrahimi     case 0x1:
481*f5c631daSSadaf Ebrahimi     case 0x3:
482*f5c631daSSadaf Ebrahimi     case 0x5:
483*f5c631daSSadaf Ebrahimi     case 0x7:
484*f5c631daSSadaf Ebrahimi       return I32;
485*f5c631daSSadaf Ebrahimi     case 0x9:
486*f5c631daSSadaf Ebrahimi     case 0xb:
487*f5c631daSSadaf Ebrahimi       return I16;
488*f5c631daSSadaf Ebrahimi     default:
489*f5c631daSSadaf Ebrahimi       break;
490*f5c631daSSadaf Ebrahimi   }
491*f5c631daSSadaf Ebrahimi   VIXL_UNREACHABLE();
492*f5c631daSSadaf Ebrahimi   return kDataTypeValueInvalid;
493*f5c631daSSadaf Ebrahimi }
494*f5c631daSSadaf Ebrahimi 
495*f5c631daSSadaf Ebrahimi 
DecodeImmediate(uint32_t cmode,uint32_t immediate)496*f5c631daSSadaf Ebrahimi NeonImmediate ImmediateVorr::DecodeImmediate(uint32_t cmode,
497*f5c631daSSadaf Ebrahimi                                              uint32_t immediate) {
498*f5c631daSSadaf Ebrahimi   switch (cmode) {
499*f5c631daSSadaf Ebrahimi     case 0x1:
500*f5c631daSSadaf Ebrahimi     case 0x9:
501*f5c631daSSadaf Ebrahimi       return immediate;
502*f5c631daSSadaf Ebrahimi     case 0x3:
503*f5c631daSSadaf Ebrahimi     case 0xb:
504*f5c631daSSadaf Ebrahimi       return immediate << 8;
505*f5c631daSSadaf Ebrahimi     case 0x5:
506*f5c631daSSadaf Ebrahimi       return immediate << 16;
507*f5c631daSSadaf Ebrahimi     case 0x7:
508*f5c631daSSadaf Ebrahimi       return immediate << 24;
509*f5c631daSSadaf Ebrahimi     default:
510*f5c631daSSadaf Ebrahimi       break;
511*f5c631daSSadaf Ebrahimi   }
512*f5c631daSSadaf Ebrahimi   VIXL_UNREACHABLE();
513*f5c631daSSadaf Ebrahimi   return 0;
514*f5c631daSSadaf Ebrahimi }
515*f5c631daSSadaf Ebrahimi 
516*f5c631daSSadaf Ebrahimi // MemOperand
517*f5c631daSSadaf Ebrahimi 
operator <<(std::ostream & os,const MemOperand & operand)518*f5c631daSSadaf Ebrahimi std::ostream& operator<<(std::ostream& os, const MemOperand& operand) {
519*f5c631daSSadaf Ebrahimi   os << "[" << operand.GetBaseRegister();
520*f5c631daSSadaf Ebrahimi   if (operand.GetAddrMode() == PostIndex) {
521*f5c631daSSadaf Ebrahimi     os << "]";
522*f5c631daSSadaf Ebrahimi     if (operand.IsRegisterOnly()) return os << "!";
523*f5c631daSSadaf Ebrahimi   }
524*f5c631daSSadaf Ebrahimi   if (operand.IsImmediate()) {
525*f5c631daSSadaf Ebrahimi     if ((operand.GetOffsetImmediate() != 0) || operand.GetSign().IsMinus() ||
526*f5c631daSSadaf Ebrahimi         ((operand.GetAddrMode() != Offset) && !operand.IsRegisterOnly())) {
527*f5c631daSSadaf Ebrahimi       if (operand.GetOffsetImmediate() == 0) {
528*f5c631daSSadaf Ebrahimi         os << ", #" << operand.GetSign() << operand.GetOffsetImmediate();
529*f5c631daSSadaf Ebrahimi       } else {
530*f5c631daSSadaf Ebrahimi         os << ", #" << operand.GetOffsetImmediate();
531*f5c631daSSadaf Ebrahimi       }
532*f5c631daSSadaf Ebrahimi     }
533*f5c631daSSadaf Ebrahimi   } else if (operand.IsPlainRegister()) {
534*f5c631daSSadaf Ebrahimi     os << ", " << operand.GetSign() << operand.GetOffsetRegister();
535*f5c631daSSadaf Ebrahimi   } else if (operand.IsShiftedRegister()) {
536*f5c631daSSadaf Ebrahimi     os << ", " << operand.GetSign() << operand.GetOffsetRegister()
537*f5c631daSSadaf Ebrahimi        << ImmediateShiftOperand(operand.GetShift(), operand.GetShiftAmount());
538*f5c631daSSadaf Ebrahimi   } else {
539*f5c631daSSadaf Ebrahimi     VIXL_UNREACHABLE();
540*f5c631daSSadaf Ebrahimi     return os;
541*f5c631daSSadaf Ebrahimi   }
542*f5c631daSSadaf Ebrahimi   if (operand.GetAddrMode() == Offset) {
543*f5c631daSSadaf Ebrahimi     os << "]";
544*f5c631daSSadaf Ebrahimi   } else if (operand.GetAddrMode() == PreIndex) {
545*f5c631daSSadaf Ebrahimi     os << "]!";
546*f5c631daSSadaf Ebrahimi   }
547*f5c631daSSadaf Ebrahimi   return os;
548*f5c631daSSadaf Ebrahimi }
549*f5c631daSSadaf Ebrahimi 
operator <<(std::ostream & os,const AlignedMemOperand & operand)550*f5c631daSSadaf Ebrahimi std::ostream& operator<<(std::ostream& os, const AlignedMemOperand& operand) {
551*f5c631daSSadaf Ebrahimi   os << "[" << operand.GetBaseRegister() << operand.GetAlignment() << "]";
552*f5c631daSSadaf Ebrahimi   if (operand.GetAddrMode() == PostIndex) {
553*f5c631daSSadaf Ebrahimi     if (operand.IsPlainRegister()) {
554*f5c631daSSadaf Ebrahimi       os << ", " << operand.GetOffsetRegister();
555*f5c631daSSadaf Ebrahimi     } else {
556*f5c631daSSadaf Ebrahimi       os << "!";
557*f5c631daSSadaf Ebrahimi     }
558*f5c631daSSadaf Ebrahimi   }
559*f5c631daSSadaf Ebrahimi   return os;
560*f5c631daSSadaf Ebrahimi }
561*f5c631daSSadaf Ebrahimi 
562*f5c631daSSadaf Ebrahimi }  // namespace aarch32
563*f5c631daSSadaf Ebrahimi }  // namespace vixl
564