1// Copyright (c) 2010 ARM Limited
2// All rights reserved
3//
4// The license below extends only to copyright in the software and shall
5// not be construed as granting a license to any other intellectual
6// property including but not limited to intellectual property relating
7// to a hardware implementation of the functionality of the software
8// licensed hereunder.  You may use the software subject to the license
9// terms below provided that you ensure that this notice is replicated
10// unmodified and in its entirety in all distributions of the software,
11// modified or unmodified, in source code or in binary form.
12//
13// Redistribution and use in source and binary forms, with or without
14// modification, are permitted provided that the following conditions are
15// met: redistributions of source code must retain the above copyright
16// notice, this list of conditions and the following disclaimer;
17// redistributions in binary form must reproduce the above copyright
18// notice, this list of conditions and the following disclaimer in the
19// documentation and/or other materials provided with the distribution;
20// neither the name of the copyright holders nor the names of its
21// contributors may be used to endorse or promote products derived from
22// this software without specific prior written permission.
23//
24// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
27// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
28// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
29// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
30// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
31// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
32// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
34// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35//
36// Authors: Gabe Black
37
38def format ArmMultAndMultAcc() {{
39    decode_block = '''
40    {
41        // The manual defines this field as 23-20, but bit 20 is usually
42        // ignored.
43        const uint32_t op = bits(machInst, 23, 21);
44        const bool s = bits(machInst, 20);
45        const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
46        const IntRegIndex ra = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
47        const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
48        const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
49        switch (op) {
50            case 0x0:
51              if (s) {
52                  return new MulCc(machInst, rd, rm, rn);
53              } else {
54                  return new Mul(machInst, rd, rm, rn);
55              }
56            case 0x1:
57              if (s) {
58                  return new MlaCc(machInst, rd, rn, rm, ra);
59              } else {
60                  return new Mla(machInst, rd, rn, rm, ra);
61              }
62            case 0x2:
63              return new Umaal(machInst, ra, rd, rn, rm);
64            case 0x3:
65              return new Mls(machInst, rd, rn, rm, ra);
66            case 0x4:
67              if (s) {
68                  return new UmullCc(machInst, ra, rd, rn, rm);
69              } else {
70                  return new Umull(machInst, ra, rd, rn, rm);
71              }
72            case 0x5:
73              if (s) {
74                  return new UmlalCc(machInst, ra, rd, rn, rm);
75              } else {
76                  return new Umlal(machInst, ra, rd, rn, rm);
77              }
78            case 0x6:
79              if (s) {
80                  return new SmullCc(machInst, ra, rd, rn, rm);
81              } else {
82                  return new Smull(machInst, ra, rd, rn, rm);
83              }
84            case 0x7:
85              if (s) {
86                  return new SmlalCc(machInst, ra, rd, rn, rm);
87              } else {
88                  return new Smlal(machInst, ra, rd, rn, rm);
89              }
90            default:
91              M5_UNREACHABLE;
92        }
93    }
94    '''
95}};
96
97def format ArmHalfWordMultAndMultAcc() {{
98    decode_block = '''
99    {
100        const uint32_t op1 = bits(machInst, 22, 21);
101        const bool op = bits(machInst, 5);
102        const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
103        const IntRegIndex ra = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
104        const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
105        const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
106        switch (op1) {
107          case 0x0:
108            switch (bits(machInst, 6, 5)) {
109              case 0x0:
110                return new SmlabbCc(machInst, rd, rn, rm, ra);
111              case 0x1:
112                return new SmlatbCc(machInst, rd, rn, rm, ra);
113              case 0x2:
114                return new SmlabtCc(machInst, rd, rn, rm, ra);
115              case 0x3:
116                return new SmlattCc(machInst, rd, rn, rm, ra);
117              default:
118                M5_UNREACHABLE;
119            }
120          case 0x1:
121            if (op) {
122                if (bits(machInst, 6)) {
123                    return new Smulwt(machInst, rd, rn, rm);
124                } else {
125                    return new Smulwb(machInst, rd, rn, rm);
126                }
127            } else {
128                if (bits(machInst, 6)) {
129                    return new SmlawtCc(machInst, rd, rn, rm, ra);
130                } else {
131                    return new SmlawbCc(machInst, rd, rn, rm, ra);
132                }
133            }
134          case 0x2:
135            switch (bits(machInst, 6, 5)) {
136              case 0x0:
137                return new Smlalbb(machInst, ra, rd, rn, rm);
138              case 0x1:
139                return new Smlaltb(machInst, ra, rd, rn, rm);
140              case 0x2:
141                return new Smlalbt(machInst, ra, rd, rn, rm);
142              case 0x3:
143                return new Smlaltt(machInst, ra, rd, rn, rm);
144              default:
145                M5_UNREACHABLE;
146            }
147          case 0x3:
148            switch (bits(machInst, 6, 5)) {
149              case 0x0:
150                return new Smulbb(machInst, rd, rn, rm);
151              case 0x1:
152                return new Smultb(machInst, rd, rn, rm);
153              case 0x2:
154                return new Smulbt(machInst, rd, rn, rm);
155              case 0x3:
156                return new Smultt(machInst, rd, rn, rm);
157              default:
158                M5_UNREACHABLE;
159            }
160          default:
161            M5_UNREACHABLE;
162        }
163    }
164    '''
165}};
166
167def format Thumb32MulMulAccAndAbsDiff() {{
168    decode_block = '''
169    {
170        const uint32_t op1 = bits(machInst, 22, 20);
171        const uint32_t op2 = bits(machInst, 5, 4);
172        const IntRegIndex ra = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
173        const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
174        const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
175        const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
176        if (op1 != 0x1 && bits(op2, 1) != 0) {
177            return new Unknown(machInst);
178        }
179        switch (op1) {
180          case 0x0:
181            if (op2 == 0) {
182                if (ra == 0xf) {
183                    return new Mul(machInst, rd, rn, rm);
184                } else {
185                    return new Mla(machInst, rd, rn, rm, ra);
186                }
187            } else {
188                return new Mls(machInst, rd, rn, rm, ra);
189            }
190          case 0x1:
191            if (ra == 0xf) {
192                switch (bits(machInst, 5, 4)) {
193                  case 0x0:
194                    return new Smulbb(machInst, rd, rn, rm);
195                  case 0x1:
196                    return new Smulbt(machInst, rd, rn, rm);
197                  case 0x2:
198                    return new Smultb(machInst, rd, rn, rm);
199                  case 0x3:
200                    return new Smultt(machInst, rd, rn, rm);
201                }
202            } else {
203                switch (bits(machInst, 5, 4)) {
204                  case 0x0:
205                    return new SmlabbCc(machInst, rd, rn, rm, ra);
206                  case 0x1:
207                    return new SmlabtCc(machInst, rd, rn, rm, ra);
208                  case 0x2:
209                    return new SmlatbCc(machInst, rd, rn, rm, ra);
210                  case 0x3:
211                    return new SmlattCc(machInst, rd, rn, rm, ra);
212                }
213            }
214            M5_UNREACHABLE;
215          case 0x2:
216            if (ra == 0xf) {
217                if (bits(machInst, 4)) {
218                    return new SmuadxCc(machInst, rd, rn, rm);
219                } else {
220                    return new SmuadCc(machInst, rd, rn, rm);
221                }
222            } else {
223                if (bits(machInst, 4)) {
224                    return new SmladxCc(machInst, rd, rn, rm, ra);
225                } else {
226                    return new SmladCc(machInst, rd, rn, rm, ra);
227                }
228            }
229          case 0x3:
230            if (ra == 0xf) {
231                if (bits(machInst, 4)) {
232                    return new Smulwt(machInst, rd, rn, rm);
233                } else {
234                    return new Smulwb(machInst, rd, rn, rm);
235                }
236            } else {
237                if (bits(machInst, 4)) {
238                    return new SmlawtCc(machInst, rd, rn, rm, ra);
239                } else {
240                    return new SmlawbCc(machInst, rd, rn, rm, ra);
241                }
242            }
243          case 0x4:
244            if (ra == 0xf) {
245                if (bits(machInst, 4)) {
246                    return new Smusdx(machInst, rd, rn, rm);
247                } else {
248                    return new Smusd(machInst, rd, rn, rm);
249                }
250            } else {
251                if (bits(machInst, 4)) {
252                    return new SmlsdxCc(machInst, rd, rn, rm, ra);
253                } else {
254                    return new SmlsdCc(machInst, rd, rn, rm, ra);
255                }
256            }
257          case 0x5:
258            if (ra == 0xf) {
259                if (bits(machInst, 4)) {
260                    return new Smmulr(machInst, rd, rn, rm);
261                } else {
262                    return new Smmul(machInst, rd, rn, rm);
263                }
264            } else {
265                if (bits(machInst, 4)) {
266                    return new Smmlar(machInst, rd, rn, rm, ra);
267                } else {
268                    return new Smmla(machInst, rd, rn, rm, ra);
269                }
270            }
271          case 0x6:
272            if (bits(machInst, 4)) {
273                return new Smmlsr(machInst, rd, rn, rm, ra);
274            } else {
275                return new Smmls(machInst, rd, rn, rm, ra);
276            }
277          case 0x7:
278            if (op2 != 0x0) {
279                return new Unknown(machInst);
280            } else if (ra == 0xf) {
281                return new Usad8(machInst, rd, rn, rm);
282            } else {
283                return new Usada8(machInst, rd, rn, rm, ra);
284            }
285          default:
286            M5_UNREACHABLE;
287        }
288    }
289    '''
290}};
291
292def format Thumb32LongMulMulAccAndDiv() {{
293    decode_block = '''
294    {
295        const uint32_t op1 = bits(machInst, 22, 20);
296        const uint32_t op2 = bits(machInst, 7, 4);
297        const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
298        const IntRegIndex rdlo = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
299        const IntRegIndex rdhi = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
300        const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
301        switch (op1) {
302          case 0x0:
303            if (op2 == 0x0) {
304                return new Smull(machInst, rdlo, rdhi, rn, rm);
305            }
306            break;
307          case 0x1:
308            if (op2 == 0xf) {
309                return new Sdiv(machInst, rdhi, rn, rm);
310            }
311            break;
312          case 0x2:
313            if (op2 == 0x0) {
314                return new Umull(machInst, rdlo, rdhi, rn, rm);
315            }
316            break;
317          case 0x3:
318            if (op2 == 0xf) {
319                return new Udiv(machInst, rdhi, rn, rm);
320            }
321            break;
322          case 0x4:
323            if (op2 == 0) {
324                return new Smlal(machInst, rdlo, rdhi, rn, rm);
325            } else if (bits(op2, 3, 2) == 0x2) {
326                switch (bits(machInst, 5, 4)) {
327                  case 0x0:
328                    return new Smlalbb(machInst, rdlo, rdhi, rn, rm);
329                  case 0x1:
330                    return new Smlalbt(machInst, rdlo, rdhi, rn, rm);
331                  case 0x2:
332                    return new Smlaltb(machInst, rdlo, rdhi, rn, rm);
333                  case 0x3:
334                    return new Smlaltt(machInst, rdlo, rdhi, rn, rm);
335                }
336            } else if (bits(op2, 3, 1) == 0x6) {
337                if (bits(machInst, 4)) {
338                    return new Smlaldx(machInst, rdlo, rdhi, rn, rm);
339                } else {
340                    return new Smlald(machInst, rdlo, rdhi, rn, rm);
341                }
342            }
343            break;
344          case 0x5:
345            if (bits(op2, 3, 1) == 0x6) {
346                if (bits(machInst, 4)) {
347                    return new Smlsldx(machInst, rdlo, rdhi, rn, rm);
348                } else {
349                    return new Smlsld(machInst, rdlo, rdhi, rn, rm);
350                }
351            }
352            break;
353          case 0x6:
354            if (op2 == 0) {
355                return new Umlal(machInst, rdlo, rdhi, rn, rm);
356            } else if (op2 == 0x6) {
357                return new Umaal(machInst, rdlo, rdhi, rn, rm);
358            }
359            break;
360        }
361        return new Unknown(machInst);
362    }
363    '''
364}};
365
366def format ArmSignedMultiplies() {{
367    decode_block = '''
368    {
369        const uint32_t op1 = bits(machInst, 22, 20);
370        // This is 7-5 in the manual, but bit 5 is always ignored.
371        const uint32_t op2 = bits(machInst, 7, 6);
372        const bool aIsF = (bits(machInst, 15, 12) == 0xf);
373        const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
374        const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
375        const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
376        const IntRegIndex ra = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
377        const bool m = bits(machInst, 5);
378        switch (op1) {
379          case 0x0:
380            if (op2 == 0) {
381                if (aIsF) {
382                    if (m) {
383                        return new SmuadxCc(machInst, rd, rn, rm);
384                    } else {
385                        return new SmuadCc(machInst, rd, rn, rm);
386                    }
387                } else {
388                    if (m) {
389                        return new SmladxCc(machInst, rd, rn, rm, ra);
390                    } else {
391                        return new SmladCc(machInst, rd, rn, rm, ra);
392                    }
393                }
394            } else if (op2 == 1) {
395                if (aIsF) {
396                    if (m) {
397                        return new Smusdx(machInst, rd, rn, rm);
398                    } else {
399                        return new Smusd(machInst, rd, rn, rm);
400                    }
401                } else {
402                    if (m) {
403                        return new SmlsdxCc(machInst, rd, rn, rm, ra);
404                    } else {
405                        return new SmlsdCc(machInst, rd, rn, rm, ra);
406                    }
407                }
408            }
409            break;
410          case 0x1:
411            if (op2 == 0 && m == 0 && ra == 0xf) {
412                return new Sdiv(machInst, rd, rn, rm);
413            }
414            break;
415          case 0x3:
416            if (op2 == 0 && m == 0 && ra == 0xf) {
417                return new Udiv(machInst, rd, rn, rm);
418            }
419            break;
420          case 0x4:
421            if (op2 == 0) {
422                if (m) {
423                    return new Smlaldx(machInst, ra, rd, rn, rm);
424                } else {
425                    return new Smlald(machInst, ra, rd, rn, rm);
426                }
427            } else if (op2 == 1) {
428                if (m) {
429                    return new Smlsldx(machInst, ra, rd, rn, rm);
430                } else {
431                    return new Smlsld(machInst, ra, rd, rn, rm);
432                }
433            }
434            break;
435          case 0x5:
436            if (op2 == 0) {
437                if (aIsF) {
438                    if (m) {
439                        return new Smmulr(machInst, rd, rn, rm);
440                    } else {
441                        return new Smmul(machInst, rd, rn, rm);
442                    }
443                } else {
444                    if (m) {
445                        return new Smmlar(machInst, rd, rn, rm, ra);
446                    } else {
447                        return new Smmla(machInst, rd, rn, rm, ra);
448                    }
449                }
450            } else if (op2 == 0x3) {
451                if (m) {
452                    return new Smmlsr(machInst, rd, rn, rm, ra);
453                } else {
454                    return new Smmls(machInst, rd, rn, rm, ra);
455                }
456            }
457            break;
458          default:
459            break;
460        }
461        return new Unknown(machInst);
462    }
463    '''
464}};
465