mult.isa revision 7229
12100SN/A// -*- mode:c++ -*-
22100SN/A
32754Sksewell@umich.edu// Copyright (c) 2010 ARM Limited
42706Sksewell@umich.edu// All rights reserved
52706Sksewell@umich.edu//
62706Sksewell@umich.edu// The license below extends only to copyright in the software and shall
72706Sksewell@umich.edu// not be construed as granting a license to any other intellectual
82706Sksewell@umich.edu// property including but not limited to intellectual property relating
92706Sksewell@umich.edu// to a hardware implementation of the functionality of the software
102706Sksewell@umich.edu// licensed hereunder.  You may use the software subject to the license
112706Sksewell@umich.edu// terms below provided that you ensure that this notice is replicated
122706Sksewell@umich.edu// unmodified and in its entirety in all distributions of the software,
132706Sksewell@umich.edu// modified or unmodified, in source code or in binary form.
142706Sksewell@umich.edu//
152706Sksewell@umich.edu// Redistribution and use in source and binary forms, with or without
162706Sksewell@umich.edu// modification, are permitted provided that the following conditions are
172706Sksewell@umich.edu// met: redistributions of source code must retain the above copyright
182706Sksewell@umich.edu// notice, this list of conditions and the following disclaimer;
192706Sksewell@umich.edu// redistributions in binary form must reproduce the above copyright
202706Sksewell@umich.edu// notice, this list of conditions and the following disclaimer in the
212706Sksewell@umich.edu// documentation and/or other materials provided with the distribution;
222706Sksewell@umich.edu// neither the name of the copyright holders nor the names of its
232706Sksewell@umich.edu// contributors may be used to endorse or promote products derived from
242706Sksewell@umich.edu// this software without specific prior written permission.
252706Sksewell@umich.edu//
262706Sksewell@umich.edu// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
272706Sksewell@umich.edu// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
282706Sksewell@umich.edu// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
292706Sksewell@umich.edu// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
302706Sksewell@umich.edu// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
312706Sksewell@umich.edu// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
322100SN/A// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
332124SN/A// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
342124SN/A// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
352124SN/A// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
362124SN/A// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
372124SN/A//
382124SN/A// Authors: Gabe Black
392124SN/A
402124SN/Alet {{
412124SN/A
422124SN/A    header_output = ""
432124SN/A    decoder_output = ""
442124SN/A    exec_output = ""
452124SN/A
462124SN/A    calcQCode = '''
472124SN/A        CondCodes = CondCodes | ((resTemp & 1) << 27);
482124SN/A    '''
492124SN/A
502124SN/A    calcCcCode = '''
512124SN/A        uint16_t _iz, _in;
522124SN/A        _in = (resTemp >> %(negBit)d) & 1;
532124SN/A        _iz = ((%(zType)s)resTemp == 0);
542124SN/A
552124SN/A        CondCodes =  _in << 31 | _iz << 30 | (CondCodes & 0x3FFFFFFF);
562124SN/A
572124SN/A        DPRINTF(Arm, "(in, iz) = (%%d, %%d)\\n", _in, _iz);
582124SN/A       '''
592124SN/A
602124SN/A    def buildMultInst(mnem, doCc, unCc, regs, code, flagType):
612124SN/A        global header_output, decoder_output, exec_output
622124SN/A        cCode = carryCode[flagType]
632124SN/A        vCode = overflowCode[flagType]
642124SN/A        zType = "uint32_t"
652124SN/A        negBit = 31
662124SN/A        if flagType == "llbit":
672124SN/A            zType = "uint64_t"
682124SN/A            negBit = 63
692124SN/A        if flagType == "overflow":
702124SN/A            ccCode = calcQCode
712124SN/A        else:
722124SN/A            ccCode = calcCcCode % {
732124SN/A                "negBit": negBit,
742124SN/A                "zType": zType
752124SN/A            }
762124SN/A
772124SN/A        if not regs in (3, 4):
782124SN/A            raise Exception, "Multiplication instructions with %d " + \
792124SN/A                             "registers are not implemented"
802124SN/A
812124SN/A        if regs == 3:
822124SN/A            base = 'Mult3'
832124SN/A        else:
842124SN/A            base = 'Mult4'
852124SN/A
862124SN/A        Name = mnem.capitalize()
872124SN/A
882124SN/A        if unCc:
892124SN/A            iop = InstObjParams(mnem, Name, base,
902124SN/A                                {"code" : code,
912124SN/A                                 "predicate_test": predicateTest})
922124SN/A        if doCc:
932124SN/A            iopCc = InstObjParams(mnem + "s", Name + "Cc", base,
942124SN/A                                  {"code" : code + ccCode,
952124SN/A                                   "predicate_test": predicateTest})
962124SN/A
972124SN/A        if regs == 3:
982124SN/A            declare = Mult3Declare
992124SN/A            constructor = Mult3Constructor
1002124SN/A        else:
1012124SN/A            declare = Mult4Declare
1022124SN/A            constructor = Mult4Constructor
1032124SN/A
1042124SN/A        if unCc:
1052124SN/A            header_output += declare.subst(iop)
1062124SN/A            decoder_output += constructor.subst(iop)
1072124SN/A            exec_output += PredOpExecute.subst(iop)
1082124SN/A        if doCc:
1092124SN/A            header_output += declare.subst(iopCc)
1102124SN/A            decoder_output += constructor.subst(iopCc)
1112124SN/A            exec_output += PredOpExecute.subst(iopCc)
1122124SN/A
1132124SN/A    def buildMult3Inst(mnem, code, flagType = "logic"):
1142124SN/A        buildMultInst(mnem, True, True, 3, code, flagType)
1152124SN/A
1162124SN/A    def buildMult3InstCc(mnem, code, flagType = "logic"):
1172124SN/A        buildMultInst(mnem, True, False, 3, code, flagType)
1182124SN/A
1192124SN/A    def buildMult3InstUnCc(mnem, code, flagType = "logic"):
1202100SN/A        buildMultInst(mnem, False, True, 3, code, flagType)
1212123SN/A
1222686Sksewell@umich.edu    def buildMult4Inst(mnem, code, flagType = "logic"):
1232686Sksewell@umich.edu        buildMultInst(mnem, True, True, 4, code, flagType)
1242686Sksewell@umich.edu
1252124SN/A    def buildMult4InstCc(mnem, code, flagType = "logic"):
1262686Sksewell@umich.edu        buildMultInst(mnem, True, False, 4, code, flagType)
1272686Sksewell@umich.edu
1282686Sksewell@umich.edu    def buildMult4InstUnCc(mnem, code, flagType = "logic"):
1292686Sksewell@umich.edu        buildMultInst(mnem, False, True, 4, code, flagType)
1302686Sksewell@umich.edu
1312686Sksewell@umich.edu    buildMult4Inst    ("mla", "Reg0 = resTemp = Reg1 * Reg2 + Reg3;")
1322686Sksewell@umich.edu    buildMult4InstUnCc("mls", "Reg0 = resTemp = Reg3 - Reg1 * Reg2;")
1332686Sksewell@umich.edu    buildMult3Inst    ("mul", "Reg0 = resTemp = Reg1 * Reg2;")
1342686Sksewell@umich.edu    buildMult4InstCc  ("smlabb", '''Reg0 = resTemp =
1352686Sksewell@umich.edu                                        sext<16>(bits(Reg1, 15, 0)) *
1362686Sksewell@umich.edu                                        sext<16>(bits(Reg2.sw, 15, 0)) +
1372686Sksewell@umich.edu                                        Reg3.sw;
1382686Sksewell@umich.edu                                 resTemp = bits(resTemp, 32) !=
1392686Sksewell@umich.edu                                           bits(resTemp, 31);
1402686Sksewell@umich.edu                                 ''', "overflow")
1412686Sksewell@umich.edu    buildMult4InstCc  ("smlabt", '''Reg0 = resTemp =
1422686Sksewell@umich.edu                                        sext<16>(bits(Reg1, 15, 0)) *
1432686Sksewell@umich.edu                                        sext<16>(bits(Reg2.sw, 31, 16)) +
1442686Sksewell@umich.edu                                        Reg3.sw;
1452686Sksewell@umich.edu                                 resTemp = bits(resTemp, 32) !=
1462686Sksewell@umich.edu                                           bits(resTemp, 31);
1472123SN/A                                 ''', "overflow")
1482123SN/A    buildMult4InstCc  ("smlatb", '''Reg0 = resTemp =
1492550SN/A                                        sext<16>(bits(Reg1, 31, 16)) *
1502550SN/A                                        sext<16>(bits(Reg2.sw, 15, 0)) +
1512123SN/A                                        Reg3.sw;
1522123SN/A                                 resTemp = bits(resTemp, 32) !=
1532123SN/A                                           bits(resTemp, 31);
1542123SN/A                                 ''', "overflow")
1552123SN/A    buildMult4InstCc  ("smlatt", '''Reg0 = resTemp =
1562123SN/A                                        sext<16>(bits(Reg1, 31, 16)) *
1572239SN/A                                        sext<16>(bits(Reg2.sw, 31, 16)) +
1582239SN/A                                        Reg3.sw;
1592239SN/A                                 resTemp = bits(resTemp, 32) !=
1602239SN/A                                           bits(resTemp, 31);
1612239SN/A                                 ''', "overflow")
1622239SN/A    buildMult4InstCc  ("smlad", '''Reg0 = resTemp =
1632239SN/A                                        sext<16>(bits(Reg1, 31, 16)) *
1642239SN/A                                        sext<16>(bits(Reg2, 31, 16)) +
1652239SN/A                                        sext<16>(bits(Reg1, 15, 0)) *
1662239SN/A                                        sext<16>(bits(Reg2, 15, 0)) +
1672239SN/A                                        Reg3.sw;
1682239SN/A                                    resTemp = bits(resTemp, 32) !=
1692239SN/A                                              bits(resTemp, 31);
1702239SN/A                                ''', "overflow")
1712239SN/A    buildMult4InstCc  ("smladx", '''Reg0 = resTemp =
1722239SN/A                                         sext<16>(bits(Reg1, 31, 16)) *
1732239SN/A                                         sext<16>(bits(Reg2, 15, 0)) +
1742239SN/A                                         sext<16>(bits(Reg1, 15, 0)) *
1752239SN/A                                         sext<16>(bits(Reg2, 31, 16)) +
1762239SN/A                                         Reg3.sw;
1772239SN/A                                    resTemp = bits(resTemp, 32) !=
1782239SN/A                                              bits(resTemp, 31);
1792239SN/A                                 ''', "overflow")
1802686Sksewell@umich.edu    buildMult4Inst    ("smlal", '''resTemp = sext<32>(Reg2) * sext<32>(Reg3) +
1812135SN/A                                       (int64_t)((Reg1.ud << 32) | Reg0.ud);
1822239SN/A                                   Reg0.ud = (uint32_t)resTemp;
1832239SN/A                                   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                                        (int64_t)Reg1.sw *
288                                        (int64_t)Reg2.sw) >> 32;
289                                ''')
290    buildMult4InstUnCc("smmlar", '''Reg0 = resTemp =
291                                        ((int64_t)(Reg3.ud << 32) +
292                                         (int64_t)Reg1.sw *
293                                         (int64_t)Reg2.sw +
294                                         ULL(0x80000000)) >> 32;
295                                 ''')
296    buildMult4InstUnCc("smmls", '''Reg0 = resTemp =
297                                       ((int64_t)(Reg3.ud << 32) -
298                                        (int64_t)Reg1.sw *
299                                        (int64_t)Reg2.sw) >> 32;
300                                ''')
301    buildMult4InstUnCc("smmlsr", '''Reg0 = resTemp =
302                                        ((int64_t)(Reg3.ud << 32) -
303                                         (int64_t)Reg1.sw *
304                                         (int64_t)Reg2.sw +
305                                         ULL(0x80000000)) >> 32;
306                                 ''')
307    buildMult3InstUnCc("smmul", '''Reg0 = resTemp =
308                                       ((int64_t)Reg1.sw *
309                                        (int64_t)Reg2.sw) >> 32;
310                                ''')
311    buildMult3InstUnCc("smmulr", '''Reg0 = resTemp =
312                                        ((int64_t)Reg1.sw *
313                                         (int64_t)Reg2.sw +
314                                         ULL(0x80000000)) >> 32;
315                                 ''')
316    buildMult3InstCc  ("smuad", '''Reg0 = resTemp =
317                                        sext<16>(bits(Reg1, 15, 0)) *
318                                        sext<16>(bits(Reg2, 15, 0)) +
319                                        sext<16>(bits(Reg1, 31, 16)) *
320                                        sext<16>(bits(Reg2, 31, 16));
321                                    resTemp = bits(resTemp, 32) !=
322                                              bits(resTemp, 31);
323                                ''', "overflow")
324    buildMult3InstCc  ("smuadx", '''Reg0 = resTemp =
325                                        sext<16>(bits(Reg1, 15, 0)) *
326                                        sext<16>(bits(Reg2, 31, 16)) +
327                                        sext<16>(bits(Reg1, 31, 16)) *
328                                        sext<16>(bits(Reg2, 15, 0));
329                                    resTemp = bits(resTemp, 32) !=
330                                              bits(resTemp, 31);
331                                 ''', "overflow")
332    buildMult3InstUnCc("smulbb", '''Reg0 = resTemp =
333                                         sext<16>(bits(Reg1, 15, 0)) *
334                                         sext<16>(bits(Reg2, 15, 0));
335                                 ''')
336    buildMult3InstUnCc("smulbt", '''Reg0 = resTemp =
337                                         sext<16>(bits(Reg1, 15, 0)) *
338                                         sext<16>(bits(Reg2, 31, 16));
339                                 ''')
340    buildMult3InstUnCc("smultb", '''Reg0 = resTemp =
341                                         sext<16>(bits(Reg1, 31, 16)) *
342                                         sext<16>(bits(Reg2, 15, 0));
343                                 ''')
344    buildMult3InstUnCc("smultt", '''Reg0 = resTemp =
345                                         sext<16>(bits(Reg1, 31, 16)) *
346                                         sext<16>(bits(Reg2, 31, 16));
347                                 ''')
348    buildMult4Inst    ("smull", '''resTemp = (int64_t)Reg2.sw *
349                                             (int64_t)Reg3.sw;
350                                   Reg0 = (int32_t)resTemp;
351                                   Reg1 = (int32_t)(resTemp >> 32);
352                                ''', "llbit")
353    buildMult3InstUnCc("smulwb", '''Reg0 = resTemp =
354                                        (Reg1.sw *
355                                         sext<16>(bits(Reg2, 15, 0))) >> 16;
356                                 ''')
357    buildMult3InstUnCc("smulwt", '''Reg0 = resTemp =
358                                        (Reg1.sw *
359                                         sext<16>(bits(Reg2, 31, 16))) >> 16;
360                                 ''')
361    buildMult3InstUnCc("smusd", '''Reg0 = resTemp =
362                                        sext<16>(bits(Reg1, 15, 0)) *
363                                        sext<16>(bits(Reg2, 15, 0)) -
364                                        sext<16>(bits(Reg1, 31, 16)) *
365                                        sext<16>(bits(Reg2, 31, 16));
366                                ''')
367    buildMult3InstUnCc("smusdx", '''Reg0 = resTemp =
368                                        sext<16>(bits(Reg1, 15, 0)) *
369                                        sext<16>(bits(Reg2, 31, 16)) -
370                                        sext<16>(bits(Reg1, 31, 16)) *
371                                        sext<16>(bits(Reg2, 15, 0));
372                                 ''')
373    buildMult4InstUnCc("umaal", '''resTemp = Reg2.ud * Reg3.ud +
374                                             Reg0.ud + Reg1.ud;
375                                   Reg0.ud = (uint32_t)resTemp;
376                                   Reg1.ud = (uint32_t)(resTemp >> 32);
377                                ''')
378    buildMult4Inst    ("umlal", '''resTemp = Reg2.ud * Reg3.ud + Reg0.ud +
379                                             (Reg1.ud << 32);
380                                   Reg0.ud = (uint32_t)resTemp;
381                                   Reg1.ud = (uint32_t)(resTemp >> 32);
382                                ''', "llbit")
383    buildMult4Inst    ("umull", '''resTemp = Reg2.ud * Reg3.ud;
384                                   Reg0 = (uint32_t)resTemp;
385                                   Reg1 = (uint32_t)(resTemp >> 32);
386                                ''', "llbit")
387}};
388