mult.isa revision 7228:09302e193402
1// -*- mode:c++ -*-
2
3// Copyright (c) 2010 ARM Limited
4// All rights reserved
5//
6// The license below extends only to copyright in the software and shall
7// not be construed as granting a license to any other intellectual
8// property including but not limited to intellectual property relating
9// to a hardware implementation of the functionality of the software
10// licensed hereunder.  You may use the software subject to the license
11// terms below provided that you ensure that this notice is replicated
12// unmodified and in its entirety in all distributions of the software,
13// modified or unmodified, in source code or in binary form.
14//
15// Redistribution and use in source and binary forms, with or without
16// modification, are permitted provided that the following conditions are
17// met: redistributions of source code must retain the above copyright
18// notice, this list of conditions and the following disclaimer;
19// redistributions in binary form must reproduce the above copyright
20// notice, this list of conditions and the following disclaimer in the
21// documentation and/or other materials provided with the distribution;
22// neither the name of the copyright holders nor the names of its
23// contributors may be used to endorse or promote products derived from
24// this software without specific prior written permission.
25//
26// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
27// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
28// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
29// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
30// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
31// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
32// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
33// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
34// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
35// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
36// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37//
38// Authors: Gabe Black
39
40let {{
41
42    header_output = ""
43    decoder_output = ""
44    exec_output = ""
45
46    calcQCode = '''
47        CondCodes = CondCodes | ((resTemp & 1) << 27);
48    '''
49
50    calcCcCode = '''
51        uint16_t _iz, _in;
52        _in = (resTemp >> %(negBit)d) & 1;
53        _iz = ((%(zType)s)resTemp == 0);
54
55        CondCodes =  _in << 31 | _iz << 30 | (CondCodes & 0x3FFFFFFF);
56
57        DPRINTF(Arm, "(in, iz) = (%%d, %%d)\\n", _in, _iz);
58       '''
59
60    def buildMultInst(mnem, doCc, unCc, regs, code, flagType):
61        global header_output, decoder_output, exec_output
62        cCode = carryCode[flagType]
63        vCode = overflowCode[flagType]
64        zType = "uint32_t"
65        negBit = 31
66        if flagType == "llbit":
67            zType = "uint64_t"
68            negBit = 63
69        if flagType == "overflow":
70            ccCode = calcQCode
71        else:
72            ccCode = calcCcCode % {
73                "negBit": negBit,
74                "zType": zType
75            }
76
77        if not regs in (3, 4):
78            raise Exception, "Multiplication instructions with %d " + \
79                             "registers are not implemented"
80
81        if regs == 3:
82            base = 'Mult3'
83        else:
84            base = 'Mult4'
85
86        Name = mnem.capitalize()
87
88        if unCc:
89            iop = InstObjParams(mnem, Name, base,
90                                {"code" : code,
91                                 "predicate_test": predicateTest})
92        if doCc:
93            iopCc = InstObjParams(mnem + "s", Name + "Cc", base,
94                                  {"code" : code + ccCode,
95                                   "predicate_test": predicateTest})
96
97        if regs == 3:
98            declare = Mult3Declare
99            constructor = Mult3Constructor
100        else:
101            declare = Mult4Declare
102            constructor = Mult4Constructor
103
104        if unCc:
105            header_output += declare.subst(iop)
106            decoder_output += constructor.subst(iop)
107            exec_output += PredOpExecute.subst(iop)
108        if doCc:
109            header_output += declare.subst(iopCc)
110            decoder_output += constructor.subst(iopCc)
111            exec_output += PredOpExecute.subst(iopCc)
112
113    def buildMult3Inst(mnem, code, flagType = "logic"):
114        buildMultInst(mnem, True, True, 3, code, flagType)
115
116    def buildMult3InstCc(mnem, code, flagType = "logic"):
117        buildMultInst(mnem, True, False, 3, code, flagType)
118
119    def buildMult3InstUnCc(mnem, code, flagType = "logic"):
120        buildMultInst(mnem, False, True, 3, code, flagType)
121
122    def buildMult4Inst(mnem, code, flagType = "logic"):
123        buildMultInst(mnem, True, True, 4, code, flagType)
124
125    def buildMult4InstCc(mnem, code, flagType = "logic"):
126        buildMultInst(mnem, True, False, 4, code, flagType)
127
128    def buildMult4InstUnCc(mnem, code, flagType = "logic"):
129        buildMultInst(mnem, False, True, 4, code, flagType)
130
131    buildMult4Inst    ("mla", "Reg0 = resTemp = Reg1 * Reg2 + Reg3;")
132    buildMult4InstUnCc("mls", "Reg0 = resTemp = Reg3 - Reg1 * Reg2;")
133    buildMult3Inst    ("mul", "Reg0 = resTemp = Reg1 * Reg2;")
134    buildMult4InstCc  ("smlabb", '''Reg0 = resTemp =
135                                        sext<16>(bits(Reg1, 15, 0)) *
136                                        sext<16>(bits(Reg2.sw, 15, 0)) +
137                                        Reg3.sw;
138                                 resTemp = bits(resTemp, 32) !=
139                                           bits(resTemp, 31);
140                                 ''', "overflow")
141    buildMult4InstCc  ("smlabt", '''Reg0 = resTemp =
142                                        sext<16>(bits(Reg1, 15, 0)) *
143                                        sext<16>(bits(Reg2.sw, 31, 16)) +
144                                        Reg3.sw;
145                                 resTemp = bits(resTemp, 32) !=
146                                           bits(resTemp, 31);
147                                 ''', "overflow")
148    buildMult4InstCc  ("smlatb", '''Reg0 = resTemp =
149                                        sext<16>(bits(Reg1, 31, 16)) *
150                                        sext<16>(bits(Reg2.sw, 15, 0)) +
151                                        Reg3.sw;
152                                 resTemp = bits(resTemp, 32) !=
153                                           bits(resTemp, 31);
154                                 ''', "overflow")
155    buildMult4InstCc  ("smlatt", '''Reg0 = resTemp =
156                                        sext<16>(bits(Reg1, 31, 16)) *
157                                        sext<16>(bits(Reg2.sw, 31, 16)) +
158                                        Reg3.sw;
159                                 resTemp = bits(resTemp, 32) !=
160                                           bits(resTemp, 31);
161                                 ''', "overflow")
162    buildMult4InstCc  ("smlad", '''Reg0 = resTemp =
163                                        sext<16>(bits(Reg1, 31, 16)) *
164                                        sext<16>(bits(Reg2, 31, 16)) +
165                                        sext<16>(bits(Reg1, 15, 0)) *
166                                        sext<16>(bits(Reg2, 15, 0)) +
167                                        Reg3.sw;
168                                    resTemp = bits(resTemp, 32) !=
169                                              bits(resTemp, 31);
170                                ''', "overflow")
171    buildMult4InstCc  ("smladx", '''Reg0 = resTemp =
172                                         sext<16>(bits(Reg1, 31, 16)) *
173                                         sext<16>(bits(Reg2, 15, 0)) +
174                                         sext<16>(bits(Reg1, 15, 0)) *
175                                         sext<16>(bits(Reg2, 31, 16)) +
176                                         Reg3.sw;
177                                    resTemp = bits(resTemp, 32) !=
178                                              bits(resTemp, 31);
179                                 ''', "overflow")
180    buildMult4Inst    ("smlal", '''resTemp = sext<32>(Reg2) * sext<32>(Reg3) +
181                                       (int64_t)((Reg1.ud << 32) | Reg0.ud);
182                                   Reg0.ud = (uint32_t)resTemp;
183                                   Reg1.ud = (uint32_t)(resTemp >> 32);
184                                ''', "llbit")
185    buildMult4InstUnCc("smlalbb", '''resTemp = sext<16>(bits(Reg2, 15, 0)) *
186                                               sext<16>(bits(Reg3, 15, 0)) +
187                                               (int64_t)((Reg1.ud << 32) |
188                                                         Reg0.ud);
189                                     Reg0.ud = (uint32_t)resTemp;
190                                     Reg1.ud = (uint32_t)(resTemp >> 32);
191                                  ''')
192    buildMult4InstUnCc("smlalbt", '''resTemp = sext<16>(bits(Reg2, 15, 0)) *
193                                               sext<16>(bits(Reg3, 31, 16)) +
194                                               (int64_t)((Reg1.ud << 32) |
195                                                         Reg0.ud);
196                                     Reg0.ud = (uint32_t)resTemp;
197                                     Reg1.ud = (uint32_t)(resTemp >> 32);
198                                  ''')
199    buildMult4InstUnCc("smlaltb", '''resTemp = sext<16>(bits(Reg2, 31, 16)) *
200                                               sext<16>(bits(Reg3, 15, 0)) +
201                                               (int64_t)((Reg1.ud << 32) |
202                                                         Reg0.ud);
203                                     Reg0.ud = (uint32_t)resTemp;
204                                     Reg1.ud = (uint32_t)(resTemp >> 32);
205                                  ''')
206    buildMult4InstUnCc("smlaltt", '''resTemp = sext<16>(bits(Reg2, 31, 16)) *
207                                               sext<16>(bits(Reg3, 31, 16)) +
208                                               (int64_t)((Reg1.ud << 32) |
209                                                         Reg0.ud);
210                                     Reg0.ud = (uint32_t)resTemp;
211                                     Reg1.ud = (uint32_t)(resTemp >> 32);
212                                  ''')
213    buildMult4InstUnCc("smlald", '''resTemp =
214                                        sext<16>(bits(Reg2, 31, 16)) *
215                                        sext<16>(bits(Reg3, 31, 16)) +
216                                        sext<16>(bits(Reg2, 15, 0)) *
217                                        sext<16>(bits(Reg3, 15, 0)) +
218                                        (int64_t)((Reg1.ud << 32) |
219                                                  Reg0.ud);
220                                    Reg0.ud = (uint32_t)resTemp;
221                                    Reg1.ud = (uint32_t)(resTemp >> 32);
222                                 ''')
223    buildMult4InstUnCc("smlaldx", '''resTemp =
224                                         sext<16>(bits(Reg2, 31, 16)) *
225                                         sext<16>(bits(Reg3, 15, 0)) +
226                                         sext<16>(bits(Reg2, 15, 0)) *
227                                         sext<16>(bits(Reg3, 31, 16)) +
228                                         (int64_t)((Reg1.ud << 32) |
229                                                   Reg0.ud);
230                                     Reg0.ud = (uint32_t)resTemp;
231                                     Reg1.ud = (uint32_t)(resTemp >> 32);
232                                  ''')
233    buildMult4InstCc  ("smlawb", '''Reg0 = resTemp =
234                                        (Reg1.sw *
235                                         sext<16>(bits(Reg2, 15, 0)) +
236                                         ((int64_t)Reg3.sw << 16)) >> 16;
237                                    resTemp = bits(resTemp, 32) !=
238                                              bits(resTemp, 31);
239                                 ''', "overflow")
240    buildMult4InstCc  ("smlawt", '''Reg0 = resTemp =
241                                        (Reg1.sw *
242                                         sext<16>(bits(Reg2, 31, 16)) +
243                                         ((int64_t)Reg3.sw << 16)) >> 16;
244                                    resTemp = bits(resTemp, 32) !=
245                                              bits(resTemp, 31);
246                                 ''', "overflow")
247    buildMult4InstCc  ("smlsd", '''Reg0 = resTemp =
248                                       sext<16>(bits(Reg1, 15, 0)) *
249                                       sext<16>(bits(Reg2, 15, 0)) -
250                                       sext<16>(bits(Reg1, 31, 16)) *
251                                       sext<16>(bits(Reg2, 31, 16)) +
252                                       Reg3.sw;
253                                    resTemp = bits(resTemp, 32) !=
254                                              bits(resTemp, 31);
255                                ''', "overflow")
256    buildMult4InstCc  ("smlsdx", '''Reg0 = resTemp =
257                                        sext<16>(bits(Reg1, 15, 0)) *
258                                        sext<16>(bits(Reg2, 31, 16)) -
259                                        sext<16>(bits(Reg1, 31, 16)) *
260                                        sext<16>(bits(Reg2, 15, 0)) +
261                                        Reg3.sw;
262                                    resTemp = bits(resTemp, 32) !=
263                                              bits(resTemp, 31);
264                                 ''', "overflow")
265    buildMult4InstUnCc("smlsld", '''resTemp =
266                                        sext<16>(bits(Reg2, 15, 0)) *
267                                        sext<16>(bits(Reg3, 15, 0)) -
268                                        sext<16>(bits(Reg2, 31, 16)) *
269                                        sext<16>(bits(Reg3, 31, 16)) +
270                                        (int64_t)((Reg1.ud << 32) |
271                                                  Reg0.ud);
272                                    Reg0.ud = (uint32_t)resTemp;
273                                    Reg1.ud = (uint32_t)(resTemp >> 32);
274                                 ''')
275    buildMult4InstUnCc("smlsldx", '''resTemp =
276                                         sext<16>(bits(Reg2, 15, 0)) *
277                                         sext<16>(bits(Reg3, 31, 16)) -
278                                         sext<16>(bits(Reg2, 31, 16)) *
279                                         sext<16>(bits(Reg3, 15, 0)) +
280                                         (int64_t)((Reg1.ud << 32) |
281                                                   Reg0.ud);
282                                     Reg0.ud = (uint32_t)resTemp;
283                                     Reg1.ud = (uint32_t)(resTemp >> 32);
284                                  ''')
285    buildMult4InstUnCc("smmla", '''Reg0 = resTemp =
286                                       ((int64_t)(Reg3.ud << 32) +
287                                        Reg1.sw * Reg2.sw) >> 32;
288                                ''')
289    buildMult4InstUnCc("smmlar", '''Reg0 = resTemp =
290                                        ((int64_t)(Reg3.ud << 32) +
291                                         Reg1.sw * Reg2.sw +
292                                         ULL(0x80000000)) >> 32;
293                                 ''')
294    buildMult4InstUnCc("smmls", '''Reg0 = resTemp =
295                                       ((int64_t)(Reg3.ud << 32) -
296                                        Reg1.sw * Reg2.sw) >> 32;
297                                ''')
298    buildMult4InstUnCc("smmlsr", '''Reg0 = resTemp =
299                                        ((int64_t)(Reg3.ud << 32) -
300                                         Reg1.sw * Reg2.sw +
301                                         ULL(0x80000000)) >> 32;
302                                 ''')
303    buildMult3InstUnCc("smmul", '''Reg0 = resTemp =
304                                       ((int64_t)Reg1 *
305                                        (int64_t)Reg2) >> 32;
306                                ''')
307    buildMult3InstUnCc("smmulr", '''Reg0 = resTemp =
308                                        ((int64_t)Reg1 *
309                                         (int64_t)Reg2 +
310                                         ULL(0x80000000)) >> 32;
311                                 ''')
312    buildMult3InstCc  ("smuad", '''Reg0 = resTemp =
313                                        sext<16>(bits(Reg1, 15, 0)) *
314                                        sext<16>(bits(Reg2, 15, 0)) +
315                                        sext<16>(bits(Reg1, 31, 16)) *
316                                        sext<16>(bits(Reg2, 31, 16));
317                                    resTemp = bits(resTemp, 32) !=
318                                              bits(resTemp, 31);
319                                ''', "overflow")
320    buildMult3InstCc  ("smuadx", '''Reg0 = resTemp =
321                                        sext<16>(bits(Reg1, 15, 0)) *
322                                        sext<16>(bits(Reg2, 31, 16)) +
323                                        sext<16>(bits(Reg1, 31, 16)) *
324                                        sext<16>(bits(Reg2, 15, 0));
325                                    resTemp = bits(resTemp, 32) !=
326                                              bits(resTemp, 31);
327                                 ''', "overflow")
328    buildMult3InstUnCc("smulbb", '''Reg0 = resTemp =
329                                         sext<16>(bits(Reg1, 15, 0)) *
330                                         sext<16>(bits(Reg2, 15, 0));
331                                 ''')
332    buildMult3InstUnCc("smulbt", '''Reg0 = resTemp =
333                                         sext<16>(bits(Reg1, 15, 0)) *
334                                         sext<16>(bits(Reg2, 31, 16));
335                                 ''')
336    buildMult3InstUnCc("smultb", '''Reg0 = resTemp =
337                                         sext<16>(bits(Reg1, 31, 16)) *
338                                         sext<16>(bits(Reg2, 15, 0));
339                                 ''')
340    buildMult3InstUnCc("smultt", '''Reg0 = resTemp =
341                                         sext<16>(bits(Reg1, 31, 16)) *
342                                         sext<16>(bits(Reg2, 31, 16));
343                                 ''')
344    buildMult4Inst    ("smull", '''resTemp = (int64_t)Reg2.sw *
345                                             (int64_t)Reg3.sw;
346                                   Reg0 = (int32_t)resTemp;
347                                   Reg1 = (int32_t)(resTemp >> 32);
348                                ''', "llbit")
349    buildMult3InstUnCc("smulwb", '''Reg0 = resTemp =
350                                        (Reg1.sw *
351                                         sext<16>(bits(Reg2, 15, 0))) >> 16;
352                                 ''')
353    buildMult3InstUnCc("smulwt", '''Reg0 = resTemp =
354                                        (Reg1.sw *
355                                         sext<16>(bits(Reg2, 31, 16))) >> 16;
356                                 ''')
357    buildMult3InstUnCc("smusd", '''Reg0 = resTemp =
358                                        sext<16>(bits(Reg1, 15, 0)) *
359                                        sext<16>(bits(Reg2, 15, 0)) -
360                                        sext<16>(bits(Reg1, 31, 16)) *
361                                        sext<16>(bits(Reg2, 31, 16));
362                                ''')
363    buildMult3InstUnCc("smusdx", '''Reg0 = resTemp =
364                                        sext<16>(bits(Reg1, 15, 0)) *
365                                        sext<16>(bits(Reg2, 31, 16)) -
366                                        sext<16>(bits(Reg1, 31, 16)) *
367                                        sext<16>(bits(Reg2, 15, 0));
368                                 ''')
369    buildMult4InstUnCc("umaal", '''resTemp = Reg2.ud * Reg3.ud +
370                                             Reg0.ud + Reg1.ud;
371                                   Reg0.ud = (uint32_t)resTemp;
372                                   Reg1.ud = (uint32_t)(resTemp >> 32);
373                                ''')
374    buildMult4Inst    ("umlal", '''resTemp = Reg2.ud * Reg3.ud + Reg0.ud +
375                                             (Reg1.ud << 32);
376                                   Reg0.ud = (uint32_t)resTemp;
377                                   Reg1.ud = (uint32_t)(resTemp >> 32);
378                                ''', "llbit")
379    buildMult4Inst    ("umull", '''resTemp = Reg2.ud * Reg3.ud;
380                                   Reg0 = (uint32_t)resTemp;
381                                   Reg1 = (uint32_t)(resTemp >> 32);
382                                ''', "llbit")
383}};
384