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 CpsrQ = (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 CondCodesNZ = (_in << 1) | _iz; 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": pickPredicate(code), 92 "op_class": "IntMultOp" }) 93 if doCc: 94 iopCc = InstObjParams(mnem + "s", Name + "Cc", base, 95 {"code" : code + ccCode, 96 "predicate_test": pickPredicate(code + ccCode), 97 "op_class": "IntMultOp" }) 98 99 if regs == 3: 100 declare = Mult3Declare 101 constructor = Mult3Constructor 102 else: 103 declare = Mult4Declare 104 constructor = Mult4Constructor 105 106 if unCc: 107 header_output += declare.subst(iop) 108 decoder_output += constructor.subst(iop) 109 exec_output += PredOpExecute.subst(iop) 110 if doCc: 111 header_output += declare.subst(iopCc) 112 decoder_output += constructor.subst(iopCc) 113 exec_output += PredOpExecute.subst(iopCc) 114 115 def buildMult3Inst(mnem, code, flagType = "logic"): 116 buildMultInst(mnem, True, True, 3, code, flagType) 117 118 def buildMult3InstCc(mnem, code, flagType = "logic"): 119 buildMultInst(mnem, True, False, 3, code, flagType) 120 121 def buildMult3InstUnCc(mnem, code, flagType = "logic"): 122 buildMultInst(mnem, False, True, 3, code, flagType) 123 124 def buildMult4Inst(mnem, code, flagType = "logic"): 125 buildMultInst(mnem, True, True, 4, code, flagType) 126 127 def buildMult4InstCc(mnem, code, flagType = "logic"): 128 buildMultInst(mnem, True, False, 4, code, flagType) 129 130 def buildMult4InstUnCc(mnem, code, flagType = "logic"): 131 buildMultInst(mnem, False, True, 4, code, flagType) 132 133 buildMult4Inst ("mla", "Reg0 = resTemp = Reg1 * Reg2 + Reg3;") 134 buildMult4InstUnCc("mls", "Reg0 = resTemp = Reg3 - Reg1 * Reg2;") 135 buildMult3Inst ("mul", "Reg0 = resTemp = Reg1 * Reg2;") 136 buildMult4InstCc ("smlabb", '''Reg0 = resTemp = 137 sext<16>(bits(Reg1, 15, 0)) * 138 sext<16>(bits(Reg2_sw, 15, 0)) + 139 Reg3_sw; 140 resTemp = bits(resTemp, 32) != 141 bits(resTemp, 31); 142 ''', "overflow") 143 buildMult4InstCc ("smlabt", '''Reg0 = resTemp = 144 sext<16>(bits(Reg1, 15, 0)) * 145 sext<16>(bits(Reg2_sw, 31, 16)) + 146 Reg3_sw; 147 resTemp = bits(resTemp, 32) != 148 bits(resTemp, 31); 149 ''', "overflow") 150 buildMult4InstCc ("smlatb", '''Reg0 = resTemp = 151 sext<16>(bits(Reg1, 31, 16)) * 152 sext<16>(bits(Reg2_sw, 15, 0)) + 153 Reg3_sw; 154 resTemp = bits(resTemp, 32) != 155 bits(resTemp, 31); 156 ''', "overflow") 157 buildMult4InstCc ("smlatt", '''Reg0 = resTemp = 158 sext<16>(bits(Reg1, 31, 16)) * 159 sext<16>(bits(Reg2_sw, 31, 16)) + 160 Reg3_sw; 161 resTemp = bits(resTemp, 32) != 162 bits(resTemp, 31); 163 ''', "overflow") 164 buildMult4InstCc ("smlad", '''Reg0 = resTemp = 165 sext<16>(bits(Reg1, 31, 16)) * 166 sext<16>(bits(Reg2, 31, 16)) + 167 sext<16>(bits(Reg1, 15, 0)) * 168 sext<16>(bits(Reg2, 15, 0)) + 169 Reg3_sw; 170 resTemp = bits(resTemp, 32) != 171 bits(resTemp, 31); 172 ''', "overflow") 173 buildMult4InstCc ("smladx", '''Reg0 = resTemp = 174 sext<16>(bits(Reg1, 31, 16)) * 175 sext<16>(bits(Reg2, 15, 0)) + 176 sext<16>(bits(Reg1, 15, 0)) * 177 sext<16>(bits(Reg2, 31, 16)) + 178 Reg3_sw; 179 resTemp = bits(resTemp, 32) != 180 bits(resTemp, 31); 181 ''', "overflow") 182 buildMult4Inst ("smlal", '''resTemp = sext<32>(Reg2) * sext<32>(Reg3) + 183 (int64_t)((Reg1_ud << 32) | Reg0_ud); 184 Reg0_ud = (uint32_t)resTemp; 185 Reg1_ud = (uint32_t)(resTemp >> 32); 186 ''', "llbit") 187 buildMult4InstUnCc("smlalbb", '''resTemp = sext<16>(bits(Reg2, 15, 0)) * 188 sext<16>(bits(Reg3, 15, 0)) + 189 (int64_t)((Reg1_ud << 32) | 190 Reg0_ud); 191 Reg0_ud = (uint32_t)resTemp; 192 Reg1_ud = (uint32_t)(resTemp >> 32); 193 ''') 194 buildMult4InstUnCc("smlalbt", '''resTemp = sext<16>(bits(Reg2, 15, 0)) * 195 sext<16>(bits(Reg3, 31, 16)) + 196 (int64_t)((Reg1_ud << 32) | 197 Reg0_ud); 198 Reg0_ud = (uint32_t)resTemp; 199 Reg1_ud = (uint32_t)(resTemp >> 32); 200 ''') 201 buildMult4InstUnCc("smlaltb", '''resTemp = sext<16>(bits(Reg2, 31, 16)) * 202 sext<16>(bits(Reg3, 15, 0)) + 203 (int64_t)((Reg1_ud << 32) | 204 Reg0_ud); 205 Reg0_ud = (uint32_t)resTemp; 206 Reg1_ud = (uint32_t)(resTemp >> 32); 207 ''') 208 buildMult4InstUnCc("smlaltt", '''resTemp = sext<16>(bits(Reg2, 31, 16)) * 209 sext<16>(bits(Reg3, 31, 16)) + 210 (int64_t)((Reg1_ud << 32) | 211 Reg0_ud); 212 Reg0_ud = (uint32_t)resTemp; 213 Reg1_ud = (uint32_t)(resTemp >> 32); 214 ''') 215 buildMult4InstUnCc("smlald", '''resTemp = 216 sext<16>(bits(Reg2, 31, 16)) * 217 sext<16>(bits(Reg3, 31, 16)) + 218 sext<16>(bits(Reg2, 15, 0)) * 219 sext<16>(bits(Reg3, 15, 0)) + 220 (int64_t)((Reg1_ud << 32) | 221 Reg0_ud); 222 Reg0_ud = (uint32_t)resTemp; 223 Reg1_ud = (uint32_t)(resTemp >> 32); 224 ''') 225 buildMult4InstUnCc("smlaldx", '''resTemp = 226 sext<16>(bits(Reg2, 31, 16)) * 227 sext<16>(bits(Reg3, 15, 0)) + 228 sext<16>(bits(Reg2, 15, 0)) * 229 sext<16>(bits(Reg3, 31, 16)) + 230 (int64_t)((Reg1_ud << 32) | 231 Reg0_ud); 232 Reg0_ud = (uint32_t)resTemp; 233 Reg1_ud = (uint32_t)(resTemp >> 32); 234 ''') 235 buildMult4InstCc ("smlawb", '''Reg0 = resTemp = 236 (Reg1_sw * 237 sext<16>(bits(Reg2, 15, 0)) + 238 ((int64_t)Reg3_sw << 16)) >> 16; 239 resTemp = bits(resTemp, 32) != 240 bits(resTemp, 31); 241 ''', "overflow") 242 buildMult4InstCc ("smlawt", '''Reg0 = resTemp = 243 (Reg1_sw * 244 sext<16>(bits(Reg2, 31, 16)) + 245 ((int64_t)Reg3_sw << 16)) >> 16; 246 resTemp = bits(resTemp, 32) != 247 bits(resTemp, 31); 248 ''', "overflow") 249 buildMult4InstCc ("smlsd", '''Reg0 = resTemp = 250 sext<16>(bits(Reg1, 15, 0)) * 251 sext<16>(bits(Reg2, 15, 0)) - 252 sext<16>(bits(Reg1, 31, 16)) * 253 sext<16>(bits(Reg2, 31, 16)) + 254 Reg3_sw; 255 resTemp = bits(resTemp, 32) != 256 bits(resTemp, 31); 257 ''', "overflow") 258 buildMult4InstCc ("smlsdx", '''Reg0 = resTemp = 259 sext<16>(bits(Reg1, 15, 0)) * 260 sext<16>(bits(Reg2, 31, 16)) - 261 sext<16>(bits(Reg1, 31, 16)) * 262 sext<16>(bits(Reg2, 15, 0)) + 263 Reg3_sw; 264 resTemp = bits(resTemp, 32) != 265 bits(resTemp, 31); 266 ''', "overflow") 267 buildMult4InstUnCc("smlsld", '''resTemp = 268 sext<16>(bits(Reg2, 15, 0)) * 269 sext<16>(bits(Reg3, 15, 0)) - 270 sext<16>(bits(Reg2, 31, 16)) * 271 sext<16>(bits(Reg3, 31, 16)) + 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("smlsldx", '''resTemp = 278 sext<16>(bits(Reg2, 15, 0)) * 279 sext<16>(bits(Reg3, 31, 16)) - 280 sext<16>(bits(Reg2, 31, 16)) * 281 sext<16>(bits(Reg3, 15, 0)) + 282 (int64_t)((Reg1_ud << 32) | 283 Reg0_ud); 284 Reg0_ud = (uint32_t)resTemp; 285 Reg1_ud = (uint32_t)(resTemp >> 32); 286 ''') 287 buildMult4InstUnCc("smmla", '''Reg0 = resTemp = 288 ((int64_t)(Reg3_ud << 32) + 289 (int64_t)Reg1_sw * 290 (int64_t)Reg2_sw) >> 32; 291 ''') 292 buildMult4InstUnCc("smmlar", '''Reg0 = resTemp = 293 ((int64_t)(Reg3_ud << 32) + 294 (int64_t)Reg1_sw * 295 (int64_t)Reg2_sw + 296 ULL(0x80000000)) >> 32; 297 ''') 298 buildMult4InstUnCc("smmls", '''Reg0 = resTemp = 299 ((int64_t)(Reg3_ud << 32) - 300 (int64_t)Reg1_sw * 301 (int64_t)Reg2_sw) >> 32; 302 ''') 303 buildMult4InstUnCc("smmlsr", '''Reg0 = resTemp = 304 ((int64_t)(Reg3_ud << 32) - 305 (int64_t)Reg1_sw * 306 (int64_t)Reg2_sw + 307 ULL(0x80000000)) >> 32; 308 ''') 309 buildMult3InstUnCc("smmul", '''Reg0 = resTemp = 310 ((int64_t)Reg1_sw * 311 (int64_t)Reg2_sw) >> 32; 312 ''') 313 buildMult3InstUnCc("smmulr", '''Reg0 = resTemp = 314 ((int64_t)Reg1_sw * 315 (int64_t)Reg2_sw + 316 ULL(0x80000000)) >> 32; 317 ''') 318 buildMult3InstCc ("smuad", '''Reg0 = resTemp = 319 sext<16>(bits(Reg1, 15, 0)) * 320 sext<16>(bits(Reg2, 15, 0)) + 321 sext<16>(bits(Reg1, 31, 16)) * 322 sext<16>(bits(Reg2, 31, 16)); 323 resTemp = bits(resTemp, 32) != 324 bits(resTemp, 31); 325 ''', "overflow") 326 buildMult3InstCc ("smuadx", '''Reg0 = resTemp = 327 sext<16>(bits(Reg1, 15, 0)) * 328 sext<16>(bits(Reg2, 31, 16)) + 329 sext<16>(bits(Reg1, 31, 16)) * 330 sext<16>(bits(Reg2, 15, 0)); 331 resTemp = bits(resTemp, 32) != 332 bits(resTemp, 31); 333 ''', "overflow") 334 buildMult3InstUnCc("smulbb", '''Reg0 = resTemp = 335 sext<16>(bits(Reg1, 15, 0)) * 336 sext<16>(bits(Reg2, 15, 0)); 337 ''') 338 buildMult3InstUnCc("smulbt", '''Reg0 = resTemp = 339 sext<16>(bits(Reg1, 15, 0)) * 340 sext<16>(bits(Reg2, 31, 16)); 341 ''') 342 buildMult3InstUnCc("smultb", '''Reg0 = resTemp = 343 sext<16>(bits(Reg1, 31, 16)) * 344 sext<16>(bits(Reg2, 15, 0)); 345 ''') 346 buildMult3InstUnCc("smultt", '''Reg0 = resTemp = 347 sext<16>(bits(Reg1, 31, 16)) * 348 sext<16>(bits(Reg2, 31, 16)); 349 ''') 350 buildMult4Inst ("smull", '''resTemp = (int64_t)Reg2_sw * 351 (int64_t)Reg3_sw; 352 Reg1 = (int32_t)(resTemp >> 32); 353 Reg0 = (int32_t)resTemp; 354 ''', "llbit") 355 buildMult3InstUnCc("smulwb", '''Reg0 = resTemp = 356 (Reg1_sw * 357 sext<16>(bits(Reg2, 15, 0))) >> 16; 358 ''') 359 buildMult3InstUnCc("smulwt", '''Reg0 = resTemp = 360 (Reg1_sw * 361 sext<16>(bits(Reg2, 31, 16))) >> 16; 362 ''') 363 buildMult3InstUnCc("smusd", '''Reg0 = resTemp = 364 sext<16>(bits(Reg1, 15, 0)) * 365 sext<16>(bits(Reg2, 15, 0)) - 366 sext<16>(bits(Reg1, 31, 16)) * 367 sext<16>(bits(Reg2, 31, 16)); 368 ''') 369 buildMult3InstUnCc("smusdx", '''Reg0 = resTemp = 370 sext<16>(bits(Reg1, 15, 0)) * 371 sext<16>(bits(Reg2, 31, 16)) - 372 sext<16>(bits(Reg1, 31, 16)) * 373 sext<16>(bits(Reg2, 15, 0)); 374 ''') 375 buildMult4InstUnCc("umaal", '''resTemp = Reg2_ud * Reg3_ud + 376 Reg0_ud + Reg1_ud; 377 Reg1_ud = (uint32_t)(resTemp >> 32); 378 Reg0_ud = (uint32_t)resTemp; 379 ''') 380 buildMult4Inst ("umlal", '''resTemp = Reg2_ud * Reg3_ud + Reg0_ud + 381 (Reg1_ud << 32); 382 Reg1_ud = (uint32_t)(resTemp >> 32); 383 Reg0_ud = (uint32_t)resTemp; 384 ''', "llbit") 385 buildMult4Inst ("umull", '''resTemp = Reg2_ud * Reg3_ud; 386 Reg1 = (uint32_t)(resTemp >> 32); 387 Reg0 = (uint32_t)resTemp; 388 ''', "llbit") 389}}; 390