mult.isa revision 7196
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 ''', "overflow") 169 buildMult4InstCc ("smladx", '''Reg0 = resTemp = 170 sext<16>(bits(Reg1, 31, 16)) * 171 sext<16>(bits(Reg2, 15, 0)) + 172 sext<16>(bits(Reg1, 15, 0)) * 173 sext<16>(bits(Reg2, 31, 16)) + 174 Reg3.sw; 175 ''', "overflow") 176 buildMult4Inst ("smlal", '''resTemp = sext<32>(Reg2) * sext<32>(Reg3) + 177 (int64_t)((Reg1.ud << 32) | Reg0.ud); 178 Reg0.ud = (uint32_t)resTemp; 179 Reg1.ud = (uint32_t)(resTemp >> 32); 180 ''', "llbit") 181 buildMult4InstUnCc("smlalbb", '''resTemp = sext<16>(bits(Reg2, 15, 0)) * 182 sext<16>(bits(Reg3, 15, 0)) + 183 (int64_t)((Reg1.ud << 32) | 184 Reg0.ud); 185 Reg0.ud = (uint32_t)resTemp; 186 Reg1.ud = (uint32_t)(resTemp >> 32); 187 ''') 188 buildMult4InstUnCc("smlalbt", '''resTemp = sext<16>(bits(Reg2, 15, 0)) * 189 sext<16>(bits(Reg3, 31, 16)) + 190 (int64_t)((Reg1.ud << 32) | 191 Reg0.ud); 192 Reg0.ud = (uint32_t)resTemp; 193 Reg1.ud = (uint32_t)(resTemp >> 32); 194 ''') 195 buildMult4InstUnCc("smlaltb", '''resTemp = sext<16>(bits(Reg2, 31, 16)) * 196 sext<16>(bits(Reg3, 15, 0)) + 197 (int64_t)((Reg1.ud << 32) | 198 Reg0.ud); 199 Reg0.ud = (uint32_t)resTemp; 200 Reg1.ud = (uint32_t)(resTemp >> 32); 201 ''') 202 buildMult4InstUnCc("smlaltt", '''resTemp = sext<16>(bits(Reg2, 31, 16)) * 203 sext<16>(bits(Reg3, 31, 16)) + 204 (int64_t)((Reg1.ud << 32) | 205 Reg0.ud); 206 Reg0.ud = (uint32_t)resTemp; 207 Reg1.ud = (uint32_t)(resTemp >> 32); 208 ''') 209 buildMult4InstUnCc("smlald", '''resTemp = 210 sext<16>(bits(Reg2, 31, 16)) * 211 sext<16>(bits(Reg3, 31, 16)) + 212 sext<16>(bits(Reg2, 15, 0)) * 213 sext<16>(bits(Reg3, 15, 0)) + 214 (int64_t)((Reg1.ud << 32) | 215 Reg0.ud); 216 Reg0.ud = (uint32_t)resTemp; 217 Reg1.ud = (uint32_t)(resTemp >> 32); 218 ''') 219 buildMult4InstUnCc("smlaldx", '''resTemp = 220 sext<16>(bits(Reg2, 31, 16)) * 221 sext<16>(bits(Reg3, 15, 0)) + 222 sext<16>(bits(Reg2, 15, 0)) * 223 sext<16>(bits(Reg3, 31, 16)) + 224 (int64_t)((Reg1.ud << 32) | 225 Reg0.ud); 226 Reg0.ud = (uint32_t)resTemp; 227 Reg1.ud = (uint32_t)(resTemp >> 32); 228 ''') 229 buildMult4InstCc ("smlawb", '''Reg0 = resTemp = 230 (Reg1.sw * 231 sext<16>(bits(Reg2, 15, 0)) + 232 ((int64_t)Reg3.sw << 16)) >> 16; 233 resTemp = bits(resTemp, 32) != 234 bits(resTemp, 31); 235 ''', "overflow") 236 buildMult4InstCc ("smlawt", '''Reg0 = resTemp = 237 (Reg1.sw * 238 sext<16>(bits(Reg2, 31, 16)) + 239 ((int64_t)Reg3.sw << 16)) >> 16; 240 resTemp = bits(resTemp, 32) != 241 bits(resTemp, 31); 242 ''', "overflow") 243 buildMult4InstCc ("smlsd", '''Reg0 = resTemp = 244 sext<16>(bits(Reg1, 15, 0)) * 245 sext<16>(bits(Reg2, 15, 0)) - 246 sext<16>(bits(Reg1, 31, 16)) * 247 sext<16>(bits(Reg2, 31, 16)) + 248 Reg3.sw; 249 ''', "overflow") 250 buildMult4InstCc ("smlsdx", '''Reg0 = resTemp = 251 sext<16>(bits(Reg1, 15, 0)) * 252 sext<16>(bits(Reg2, 31, 16)) - 253 sext<16>(bits(Reg1, 31, 16)) * 254 sext<16>(bits(Reg2, 15, 0)) + 255 Reg3.sw; 256 ''', "overflow") 257 buildMult4InstUnCc("smlsld", '''resTemp = 258 sext<16>(bits(Reg2, 15, 0)) * 259 sext<16>(bits(Reg3, 15, 0)) - 260 sext<16>(bits(Reg2, 31, 16)) * 261 sext<16>(bits(Reg3, 31, 16)) + 262 (int64_t)((Reg1.ud << 32) | 263 Reg0.ud); 264 Reg0.ud = (uint32_t)resTemp; 265 Reg1.ud = (uint32_t)(resTemp >> 32); 266 ''') 267 buildMult4InstUnCc("smlsldx", '''resTemp = 268 sext<16>(bits(Reg2, 15, 0)) * 269 sext<16>(bits(Reg3, 31, 16)) - 270 sext<16>(bits(Reg2, 31, 16)) * 271 sext<16>(bits(Reg3, 15, 0)) + 272 (int64_t)((Reg1.ud << 32) | 273 Reg0.ud); 274 Reg0.ud = (uint32_t)resTemp; 275 Reg1.ud = (uint32_t)(resTemp >> 32); 276 ''') 277 buildMult4InstUnCc("smmla", '''Reg0 = resTemp = 278 ((int64_t)(Reg3.ud << 32) + 279 Reg1.sw * Reg2.sw) >> 32; 280 ''') 281 buildMult4InstUnCc("smmlar", '''Reg0 = resTemp = 282 ((int64_t)(Reg3.ud << 32) + 283 Reg1.sw * Reg2.sw + 284 ULL(0x80000000)) >> 32; 285 ''') 286 buildMult4InstUnCc("smmls", '''Reg0 = resTemp = 287 ((int64_t)(Reg3.ud << 32) - 288 Reg1.sw * Reg2.sw) >> 32; 289 ''') 290 buildMult4InstUnCc("smmlsr", '''Reg0 = resTemp = 291 ((int64_t)(Reg3.ud << 32) - 292 Reg1.sw * Reg2.sw + 293 ULL(0x80000000)) >> 32; 294 ''') 295 buildMult3InstUnCc("smmul", '''Reg0 = resTemp = 296 ((int64_t)Reg1 * 297 (int64_t)Reg2) >> 32; 298 ''') 299 buildMult3InstUnCc("smmulr", '''Reg0 = resTemp = 300 ((int64_t)Reg1 * 301 (int64_t)Reg2 + 302 ULL(0x80000000)) >> 32; 303 ''') 304 buildMult3InstCc ("smuad", '''Reg0 = resTemp = 305 sext<16>(bits(Reg1, 15, 0)) * 306 sext<16>(bits(Reg2, 15, 0)) + 307 sext<16>(bits(Reg1, 31, 16)) * 308 sext<16>(bits(Reg2, 31, 16)); 309 ''', "overflow") 310 buildMult3InstCc ("smuadx", '''Reg0 = resTemp = 311 sext<16>(bits(Reg1, 15, 0)) * 312 sext<16>(bits(Reg2, 31, 16)) + 313 sext<16>(bits(Reg1, 31, 16)) * 314 sext<16>(bits(Reg2, 15, 0)); 315 ''', "overflow") 316 buildMult3InstUnCc("smulbb", '''Reg0 = resTemp = 317 sext<16>(bits(Reg1, 15, 0)) * 318 sext<16>(bits(Reg2, 15, 0)); 319 ''') 320 buildMult3InstUnCc("smulbt", '''Reg0 = resTemp = 321 sext<16>(bits(Reg1, 15, 0)) * 322 sext<16>(bits(Reg2, 31, 16)); 323 ''') 324 buildMult3InstUnCc("smultb", '''Reg0 = resTemp = 325 sext<16>(bits(Reg1, 31, 16)) * 326 sext<16>(bits(Reg2, 15, 0)); 327 ''') 328 buildMult3InstUnCc("smultt", '''Reg0 = resTemp = 329 sext<16>(bits(Reg1, 31, 16)) * 330 sext<16>(bits(Reg2, 31, 16)); 331 ''') 332 buildMult4Inst ("smull", '''resTemp = (int64_t)Reg2.sw * 333 (int64_t)Reg3.sw; 334 Reg0 = (int32_t)resTemp; 335 Reg1 = (int32_t)(resTemp >> 32); 336 ''', "llbit") 337 buildMult3InstUnCc("smulwb", '''Reg0 = resTemp = 338 (Reg1.sw * 339 sext<16>(bits(Reg2, 15, 0))) >> 16; 340 ''') 341 buildMult3InstUnCc("smulwt", '''Reg0 = resTemp = 342 (Reg1.sw * 343 sext<16>(bits(Reg2, 31, 16))) >> 16; 344 ''') 345 buildMult3InstUnCc("smusd", '''Reg0 = resTemp = 346 sext<16>(bits(Reg1, 15, 0)) * 347 sext<16>(bits(Reg2, 15, 0)) - 348 sext<16>(bits(Reg1, 31, 16)) * 349 sext<16>(bits(Reg2, 31, 16)); 350 ''') 351 buildMult3InstUnCc("smusdx", '''Reg0 = resTemp = 352 sext<16>(bits(Reg1, 15, 0)) * 353 sext<16>(bits(Reg2, 31, 16)) - 354 sext<16>(bits(Reg1, 31, 16)) * 355 sext<16>(bits(Reg2, 15, 0)); 356 ''') 357 buildMult4InstUnCc("umaal", '''resTemp = Reg2.ud * Reg3.ud + 358 Reg0.ud + Reg1.ud; 359 Reg0.ud = (uint32_t)resTemp; 360 Reg1.ud = (uint32_t)(resTemp >> 32); 361 ''') 362 buildMult4Inst ("umlal", '''resTemp = Reg2.ud * Reg3.ud + Reg0.ud + 363 (Reg1.ud << 32); 364 Reg0.ud = (uint32_t)resTemp; 365 Reg1.ud = (uint32_t)(resTemp >> 32); 366 ''', "llbit") 367 buildMult4Inst ("umull", '''resTemp = Reg2.ud * Reg3.ud; 368 Reg0 = (uint32_t)resTemp; 369 Reg1 = (uint32_t)(resTemp >> 32); 370 ''', "llbit") 371}}; 372