mult.isa revision 7290
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        }
91    }
92    '''
93}};
94
95def format ArmHalfWordMultAndMultAcc() {{
96    decode_block = '''
97    {
98        const uint32_t op1 = bits(machInst, 22, 21);
99        const bool op = bits(machInst, 5);
100        const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
101        const IntRegIndex ra = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
102        const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
103        const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
104        switch (op1) {
105          case 0x0:
106            switch (bits(machInst, 6, 5)) {
107              case 0x0:
108                return new SmlabbCc(machInst, rd, rn, rm, ra);
109              case 0x1:
110                return new SmlatbCc(machInst, rd, rn, rm, ra);
111              case 0x2:
112                return new SmlabtCc(machInst, rd, rn, rm, ra);
113              case 0x3:
114                return new SmlattCc(machInst, rd, rn, rm, ra);
115            }
116          case 0x1:
117            if (op) {
118                if (bits(machInst, 6)) {
119                    return new Smulwt(machInst, rd, rn, rm);
120                } else {
121                    return new Smulwb(machInst, rd, rn, rm);
122                }
123            } else {
124                if (bits(machInst, 6)) {
125                    return new SmlawtCc(machInst, rd, rn, rm, ra);
126                } else {
127                    return new SmlawbCc(machInst, rd, rn, rm, ra);
128                }
129            }
130          case 0x2:
131            switch (bits(machInst, 6, 5)) {
132              case 0x0:
133                return new Smlalbb(machInst, ra, rd, rn, rm);
134              case 0x1:
135                return new Smlaltb(machInst, ra, rd, rn, rm);
136              case 0x2:
137                return new Smlalbt(machInst, ra, rd, rn, rm);
138              case 0x3:
139                return new Smlaltt(machInst, ra, rd, rn, rm);
140            }
141          case 0x3:
142            switch (bits(machInst, 6, 5)) {
143              case 0x0:
144                return new Smulbb(machInst, rd, rn, rm);
145              case 0x1:
146                return new Smultb(machInst, rd, rn, rm);
147              case 0x2:
148                return new Smulbt(machInst, rd, rn, rm);
149              case 0x3:
150                return new Smultt(machInst, rd, rn, rm);
151            }
152        }
153    }
154    '''
155}};
156
157def format Thumb32MulMulAccAndAbsDiff() {{
158    decode_block = '''
159    {
160        const uint32_t op1 = bits(machInst, 22, 20);
161        const uint32_t op2 = bits(machInst, 5, 4);
162        const IntRegIndex ra = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
163        const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
164        const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
165        const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
166        if (op1 != 0x1 && bits(op2, 1) != 0) {
167            return new Unknown(machInst);
168        }
169        switch (op1) {
170          case 0x0:
171            if (op2 == 0) {
172                if (ra == 0xf) {
173                    return new Mul(machInst, rd, rn, rm);
174                } else {
175                    return new Mla(machInst, rd, rn, rm, ra);
176                }
177            } else {
178                return new Mls(machInst, rd, rn, rm, ra);
179            }
180          case 0x1:
181            if (ra == 0xf) {
182                switch (bits(machInst, 5, 4)) {
183                  case 0x0:
184                    return new Smulbb(machInst, rd, rn, rm);
185                  case 0x1:
186                    return new Smulbt(machInst, rd, rn, rm);
187                  case 0x2:
188                    return new Smultb(machInst, rd, rn, rm);
189                  case 0x3:
190                    return new Smultt(machInst, rd, rn, rm);
191                }
192            } else {
193                switch (bits(machInst, 5, 4)) {
194                  case 0x0:
195                    return new SmlabbCc(machInst, rd, rn, rm, ra);
196                  case 0x1:
197                    return new SmlabtCc(machInst, rd, rn, rm, ra);
198                  case 0x2:
199                    return new SmlatbCc(machInst, rd, rn, rm, ra);
200                  case 0x3:
201                    return new SmlattCc(machInst, rd, rn, rm, ra);
202                }
203            }
204          case 0x2:
205            if (ra == 0xf) {
206                if (bits(machInst, 4)) {
207                    return new SmuadxCc(machInst, rd, rn, rm);
208                } else {
209                    return new SmuadCc(machInst, rd, rn, rm);
210                }
211            } else {
212                if (bits(machInst, 4)) {
213                    return new SmladxCc(machInst, rd, rn, rm, ra);
214                } else {
215                    return new SmladCc(machInst, rd, rn, rm, ra);
216                }
217            }
218          case 0x3:
219            if (ra == 0xf) {
220                if (bits(machInst, 4)) {
221                    return new Smulwt(machInst, rd, rn, rm);
222                } else {
223                    return new Smulwb(machInst, rd, rn, rm);
224                }
225            } else {
226                if (bits(machInst, 4)) {
227                    return new SmlawtCc(machInst, rd, rn, rm, ra);
228                } else {
229                    return new SmlawbCc(machInst, rd, rn, rm, ra);
230                }
231            }
232          case 0x4:
233            if (ra == 0xf) {
234                if (bits(machInst, 4)) {
235                    return new Smusdx(machInst, rd, rn, rm);
236                } else {
237                    return new Smusd(machInst, rd, rn, rm);
238                }
239            } else {
240                if (bits(machInst, 4)) {
241                    return new SmlsdxCc(machInst, rd, rn, rm, ra);
242                } else {
243                    return new SmlsdCc(machInst, rd, rn, rm, ra);
244                }
245            }
246          case 0x5:
247            if (ra == 0xf) {
248                if (bits(machInst, 4)) {
249                    return new Smmulr(machInst, rd, rn, rm);
250                } else {
251                    return new Smmul(machInst, rd, rn, rm);
252                }
253            } else {
254                if (bits(machInst, 4)) {
255                    return new Smmlar(machInst, rd, rn, rm, ra);
256                } else {
257                    return new Smmla(machInst, rd, rn, rm, ra);
258                }
259            }
260          case 0x6:
261            if (bits(machInst, 4)) {
262                return new Smmlsr(machInst, rd, rn, rm, ra);
263            } else {
264                return new Smmls(machInst, rd, rn, rm, ra);
265            }
266          case 0x7:
267            if (op2 != 0x0) {
268                return new Unknown(machInst);
269            } else if (ra == 0xf) {
270                return new Usad8(machInst, rd, rn, rm);
271            } else {
272                return new Usada8(machInst, rd, rn, rm, ra);
273            }
274        }
275    }
276    '''
277}};
278
279def format Thumb32LongMulMulAccAndDiv() {{
280    decode_block = '''
281    {
282        const uint32_t op1 = bits(machInst, 22, 20);
283        const uint32_t op2 = bits(machInst, 7, 4);
284        const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
285        const IntRegIndex rdlo = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
286        const IntRegIndex rdhi = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
287        const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
288        switch (op1) {
289          case 0x0:
290            if (op2 == 0x0) {
291                return new Smull(machInst, rdlo, rdhi, rn, rm);
292            }
293            break;
294          case 0x1:
295            if (op2 == 0xf) {
296                return new WarnUnimplemented("sdiv", machInst);
297            }
298            break;
299          case 0x2:
300            if (op2 == 0x0) {
301                return new Umull(machInst, rdlo, rdhi, rn, rm);
302            }
303            break;
304          case 0x3:
305            if (op2 == 0xf) {
306                return new WarnUnimplemented("udiv", machInst);
307            }
308            break;
309          case 0x4:
310            if (op2 == 0) {
311                return new Smlal(machInst, rdlo, rdhi, rn, rm);
312            } else if (bits(op2, 3, 2) == 0x2) {
313                switch (bits(machInst, 5, 4)) {
314                  case 0x0:
315                    return new Smlalbb(machInst, rdlo, rdhi, rn, rm);
316                  case 0x1:
317                    return new Smlalbt(machInst, rdlo, rdhi, rn, rm);
318                  case 0x2:
319                    return new Smlaltb(machInst, rdlo, rdhi, rn, rm);
320                  case 0x3:
321                    return new Smlaltt(machInst, rdlo, rdhi, rn, rm);
322                }
323            } else if (bits(op2, 3, 1) == 0x6) {
324                if (bits(machInst, 4)) {
325                    return new Smlaldx(machInst, rdlo, rdhi, rn, rm);
326                } else {
327                    return new Smlald(machInst, rdlo, rdhi, rn, rm);
328                }
329            }
330            break;
331          case 0x5:
332            if (bits(op2, 3, 1) == 0x6) {
333                if (bits(machInst, 4)) {
334                    return new Smlsldx(machInst, rdlo, rdhi, rn, rm);
335                } else {
336                    return new Smlsld(machInst, rdlo, rdhi, rn, rm);
337                }
338            }
339            break;
340          case 0x6:
341            if (op2 == 0) {
342                return new Umlal(machInst, rdlo, rdhi, rn, rm);
343            } else if (op2 == 0x6) {
344                return new Umaal(machInst, rdlo, rdhi, rn, rm);
345            }
346            break;
347        }
348        return new Unknown(machInst);
349    }
350    '''
351}};
352
353def format ArmSignedMultiplies() {{
354    decode_block = '''
355    {
356        const uint32_t op1 = bits(machInst, 22, 20);
357        // This is 7-5 in the manual, but bit 5 is always ignored.
358        const uint32_t op2 = bits(machInst, 7, 6);
359        const bool aIsF = (bits(machInst, 15, 12) == 0xf);
360        const IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 19, 16);
361        const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 3, 0);
362        const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 11, 8);
363        const IntRegIndex ra = (IntRegIndex)(uint32_t)bits(machInst, 15, 12);
364        const bool m = bits(machInst, 5);
365        switch (op1) {
366          case 0x0:
367            if (op2 == 0) {
368                if (aIsF) {
369                    if (m) {
370                        return new SmuadxCc(machInst, rd, rn, rm);
371                    } else {
372                        return new SmuadCc(machInst, rd, rn, rm);
373                    }
374                } else {
375                    if (m) {
376                        return new SmladxCc(machInst, rd, rn, rm, ra);
377                    } else {
378                        return new SmladCc(machInst, rd, rn, rm, ra);
379                    }
380                }
381            } else if (op2 == 1) {
382                if (aIsF) {
383                    if (m) {
384                        return new Smusdx(machInst, rd, rn, rm);
385                    } else {
386                        return new Smusd(machInst, rd, rn, rm);
387                    }
388                } else {
389                    if (m) {
390                        return new SmlsdxCc(machInst, rd, rn, rm, ra);
391                    } else {
392                        return new SmlsdCc(machInst, rd, rn, rm, ra);
393                    }
394                }
395            }
396            break;
397          case 0x4:
398            if (op2 == 0) {
399                if (m) {
400                    return new Smlaldx(machInst, ra, rd, rn, rm);
401                } else {
402                    return new Smlald(machInst, ra, rd, rn, rm);
403                }
404            } else if (op2 == 1) {
405                if (m) {
406                    return new Smlsldx(machInst, ra, rd, rn, rm);
407                } else {
408                    return new Smlsld(machInst, ra, rd, rn, rm);
409                }
410            }
411            break;
412          case 0x5:
413            if (op2 == 0) {
414                if (aIsF) {
415                    if (m) {
416                        return new Smmulr(machInst, rd, rn, rm);
417                    } else {
418                        return new Smmul(machInst, rd, rn, rm);
419                    }
420                } else {
421                    if (m) {
422                        return new Smmlar(machInst, rd, rn, rm, ra);
423                    } else {
424                        return new Smmla(machInst, rd, rn, rm, ra);
425                    }
426                }
427            } else if (op2 == 0x3) {
428                if (m) {
429                    return new Smmlsr(machInst, rd, rn, rm, ra);
430                } else {
431                    return new Smmls(machInst, rd, rn, rm, ra);
432                }
433            }
434            break;
435          default:
436            break;
437        }
438        return new Unknown(machInst);
439    }
440    '''
441}};
442