mult.isa revision 7162
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 cprintf("canOverflow: %%d\\n", Reg0 < resTemp); 48 replaceBits(CondCodes, 27, Reg0 < resTemp); 49 ''' 50 51 calcCcCode = ''' 52 uint16_t _iz, _in; 53 _in = (resTemp >> %(negBit)d) & 1; 54 _iz = ((%(zType)s)resTemp == 0); 55 56 CondCodes = _in << 31 | _iz << 30 | (CondCodes & 0x3FFFFFFF); 57 58 DPRINTF(Arm, "(in, iz) = (%%d, %%d)\\n", _in, _iz); 59 ''' 60 61 def buildMultInst(mnem, doCc, unCc, regs, code, flagType): 62 global header_output, decoder_output, exec_output 63 cCode = carryCode[flagType] 64 vCode = overflowCode[flagType] 65 zType = "uint32_t" 66 negBit = 31 67 if flagType == "llbit": 68 zType = "uint64_t" 69 negBit = 63 70 if flagType == "overflow": 71 ccCode = calcQCode 72 else: 73 ccCode = calcCcCode % { 74 "negBit": negBit, 75 "zType": zType 76 } 77 78 if not regs in (3, 4): 79 raise Exception, "Multiplication instructions with %d " + \ 80 "registers are not implemented" 81 82 if regs == 3: 83 base = 'Mult3' 84 else: 85 base = 'Mult4' 86 87 Name = mnem.capitalize() 88 89 if unCc: 90 iop = InstObjParams(mnem, Name, base, 91 {"code" : code, 92 "predicate_test": predicateTest}) 93 if doCc: 94 iopCc = InstObjParams(mnem + "s", Name + "Cc", base, 95 {"code" : code + ccCode, 96 "predicate_test": predicateTest}) 97 98 if regs == 3: 99 declare = Mult3Declare 100 constructor = Mult3Constructor 101 else: 102 declare = Mult4Declare 103 constructor = Mult4Constructor 104 105 if unCc: 106 header_output += declare.subst(iop) 107 decoder_output += constructor.subst(iop) 108 exec_output += PredOpExecute.subst(iop) 109 if doCc: 110 header_output += declare.subst(iopCc) 111 decoder_output += constructor.subst(iopCc) 112 exec_output += PredOpExecute.subst(iopCc) 113 114 def buildMult3Inst(mnem, code, flagType = "logic"): 115 buildMultInst(mnem, True, True, 3, code, flagType) 116 117 def buildMult3InstCc(mnem, code, flagType = "logic"): 118 buildMultInst(mnem, True, False, 3, code, flagType) 119 120 def buildMult3InstUnCc(mnem, code, flagType = "logic"): 121 buildMultInst(mnem, False, True, 3, code, flagType) 122 123 def buildMult4Inst(mnem, code, flagType = "logic"): 124 buildMultInst(mnem, True, True, 4, code, flagType) 125 126 def buildMult4InstCc(mnem, code, flagType = "logic"): 127 buildMultInst(mnem, True, False, 4, code, flagType) 128 129 def buildMult4InstUnCc(mnem, code, flagType = "logic"): 130 buildMultInst(mnem, False, True, 4, code, flagType) 131 132 buildMult4Inst ("mla", "Reg0 = resTemp = Reg1 * Reg2 + Reg3;") 133 buildMult4InstUnCc("mls", "Reg0 = resTemp = Reg3 - Reg1 * Reg2;") 134 buildMult3Inst ("mul", "Reg0 = resTemp = Reg1 * Reg2;") 135 buildMult4InstCc ("smlabb", '''Reg0 = resTemp = 136 sext<16>(bits(Reg1, 15, 0)) * 137 sext<16>(bits(Reg2, 15, 0)) + 138 Reg3.sw; 139 ''', "overflow") 140 buildMult4InstCc ("smlabt", '''Reg0 = resTemp = 141 sext<16>(bits(Reg1, 15, 0)) * 142 sext<16>(bits(Reg2, 31, 16)) + 143 Reg3.sw; 144 ''', "overflow") 145 buildMult4InstCc ("smlatb", '''Reg0 = resTemp = 146 sext<16>(bits(Reg1, 31, 16)) * 147 sext<16>(bits(Reg2, 15, 0)) + 148 Reg3.sw; 149 ''', "overflow") 150 buildMult4InstCc ("smlatt", '''Reg0 = resTemp = 151 sext<16>(bits(Reg1, 31, 16)) * 152 sext<16>(bits(Reg2, 31, 16)) + 153 Reg3.sw; 154 ''', "overflow") 155 buildMult4InstCc ("smlad", '''Reg0 = resTemp = 156 sext<16>(bits(Reg1, 31, 16)) * 157 sext<16>(bits(Reg2, 31, 16)) + 158 sext<16>(bits(Reg1, 15, 0)) * 159 sext<16>(bits(Reg2, 15, 0)) + 160 Reg3.sw; 161 ''', "overflow") 162 buildMult4InstCc ("smladx", '''Reg0 = resTemp = 163 sext<16>(bits(Reg1, 31, 16)) * 164 sext<16>(bits(Reg2, 15, 0)) + 165 sext<16>(bits(Reg1, 15, 0)) * 166 sext<16>(bits(Reg2, 31, 16)) + 167 Reg3.sw; 168 ''', "overflow") 169 buildMult4Inst ("smlal", '''resTemp = sext<32>(Reg2) * sext<32>(Reg3) + 170 (int64_t)((Reg1.ud << 32) | Reg0.ud); 171 Reg0.ud = (uint32_t)resTemp; 172 Reg1.ud = (uint32_t)(resTemp >> 32); 173 ''', "llbit") 174 buildMult4InstUnCc("smlalbb", '''resTemp = sext<16>(bits(Reg2, 15, 0)) * 175 sext<16>(bits(Reg3, 15, 0)) + 176 (int64_t)((Reg1.ud << 32) | 177 Reg0.ud); 178 Reg0.ud = (uint32_t)resTemp; 179 Reg1.ud = (uint32_t)(resTemp >> 32); 180 ''') 181 buildMult4InstUnCc("smlalbt", '''resTemp = sext<16>(bits(Reg2, 15, 0)) * 182 sext<16>(bits(Reg3, 31, 16)) + 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("smlaltb", '''resTemp = sext<16>(bits(Reg2, 31, 16)) * 189 sext<16>(bits(Reg3, 15, 0)) + 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("smlaltt", '''resTemp = sext<16>(bits(Reg2, 31, 16)) * 196 sext<16>(bits(Reg3, 31, 16)) + 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("smlald", '''resTemp = 203 sext<16>(bits(Reg2, 31, 16)) * 204 sext<16>(bits(Reg3, 31, 16)) + 205 sext<16>(bits(Reg2, 15, 0)) * 206 sext<16>(bits(Reg3, 15, 0)) + 207 (int64_t)((Reg1.ud << 32) | 208 Reg0.ud); 209 Reg0.ud = (uint32_t)resTemp; 210 Reg1.ud = (uint32_t)(resTemp >> 32); 211 ''') 212 buildMult4InstUnCc("smlaldx", '''resTemp = 213 sext<16>(bits(Reg2, 31, 16)) * 214 sext<16>(bits(Reg3, 15, 0)) + 215 sext<16>(bits(Reg2, 15, 0)) * 216 sext<16>(bits(Reg3, 31, 16)) + 217 (int64_t)((Reg1.ud << 32) | 218 Reg0.ud); 219 Reg0.ud = (uint32_t)resTemp; 220 Reg1.ud = (uint32_t)(resTemp >> 32); 221 ''') 222 buildMult4InstCc ("smlawb", '''Reg0 = resTemp = 223 (Reg1.sw * 224 sext<16>(bits(Reg2, 15, 0)) + 225 (Reg3.sw << 16)) >> 16; 226 ''', "overflow") 227 buildMult4InstCc ("smlawt", '''Reg0 = resTemp = 228 (Reg1.sw * 229 sext<16>(bits(Reg2, 31, 16)) + 230 (Reg3.sw << 16)) >> 16; 231 ''', "overflow") 232 buildMult4InstCc ("smlsd", '''Reg0 = resTemp = 233 sext<16>(bits(Reg1, 15, 0)) * 234 sext<16>(bits(Reg2, 15, 0)) - 235 sext<16>(bits(Reg1, 31, 16)) * 236 sext<16>(bits(Reg2, 31, 16)) + 237 Reg3.sw; 238 ''', "overflow") 239 buildMult4InstCc ("smlsdx", '''Reg0 = resTemp = 240 sext<16>(bits(Reg1, 15, 0)) * 241 sext<16>(bits(Reg2, 31, 16)) - 242 sext<16>(bits(Reg1, 31, 16)) * 243 sext<16>(bits(Reg2, 15, 0)) + 244 Reg3.sw; 245 ''', "overflow") 246 buildMult4InstUnCc("smlsld", '''resTemp = 247 sext<16>(bits(Reg2, 15, 0)) * 248 sext<16>(bits(Reg3, 15, 0)) - 249 sext<16>(bits(Reg2, 31, 16)) * 250 sext<16>(bits(Reg3, 31, 16)) + 251 (int64_t)((Reg1.ud << 32) | 252 Reg0.ud); 253 Reg0.ud = (uint32_t)resTemp; 254 Reg1.ud = (uint32_t)(resTemp >> 32); 255 ''') 256 buildMult4InstUnCc("smlsldx", '''resTemp = 257 sext<16>(bits(Reg2, 15, 0)) * 258 sext<16>(bits(Reg3, 31, 16)) - 259 sext<16>(bits(Reg2, 31, 16)) * 260 sext<16>(bits(Reg3, 15, 0)) + 261 (int64_t)((Reg1.ud << 32) | 262 Reg0.ud); 263 Reg0.ud = (uint32_t)resTemp; 264 Reg1.ud = (uint32_t)(resTemp >> 32); 265 ''') 266 buildMult4InstUnCc("smmla", '''Reg0 = resTemp = 267 ((int64_t)(Reg3.ud << 32) + 268 Reg1.sw * Reg2.sw) >> 32; 269 ''') 270 buildMult4InstUnCc("smmlar", '''Reg0 = resTemp = 271 ((int64_t)(Reg3.ud << 32) + 272 Reg1.sw * Reg2.sw + 273 ULL(0x80000000)) >> 32; 274 ''') 275 buildMult4InstUnCc("smmls", '''Reg0 = resTemp = 276 ((int64_t)(Reg3.ud << 32) - 277 Reg1.sw * Reg2.sw) >> 32; 278 ''') 279 buildMult4InstUnCc("smmlsr", '''Reg0 = resTemp = 280 ((int64_t)(Reg3.ud << 32) - 281 Reg1.sw * Reg2.sw + 282 ULL(0x80000000)) >> 32; 283 ''') 284 buildMult3InstUnCc("smmul", '''Reg0 = resTemp = 285 ((int64_t)Reg1 * 286 (int64_t)Reg2) >> 32; 287 ''') 288 buildMult3InstUnCc("smmulr", '''Reg0 = resTemp = 289 ((int64_t)Reg1 * 290 (int64_t)Reg2 + 291 ULL(0x80000000)) >> 32; 292 ''') 293 buildMult3InstCc ("smuad", '''Reg0 = resTemp = 294 sext<16>(bits(Reg1, 15, 0)) * 295 sext<16>(bits(Reg2, 15, 0)) + 296 sext<16>(bits(Reg1, 31, 16)) * 297 sext<16>(bits(Reg2, 31, 16)); 298 ''', "overflow") 299 buildMult3InstCc ("smuadx", '''Reg0 = resTemp = 300 sext<16>(bits(Reg1, 15, 0)) * 301 sext<16>(bits(Reg2, 31, 16)) + 302 sext<16>(bits(Reg1, 31, 16)) * 303 sext<16>(bits(Reg2, 15, 0)); 304 ''', "overflow") 305 buildMult3InstUnCc("smulbb", '''Reg0 = resTemp = 306 sext<16>(bits(Reg1, 15, 0)) * 307 sext<16>(bits(Reg2, 15, 0)); 308 ''') 309 buildMult3InstUnCc("smulbt", '''Reg0 = resTemp = 310 sext<16>(bits(Reg1, 31, 16)) * 311 sext<16>(bits(Reg2, 15, 0)); 312 ''') 313 buildMult3InstUnCc("smultb", '''Reg0 = resTemp = 314 sext<16>(bits(Reg1, 15, 0)) * 315 sext<16>(bits(Reg2, 31, 16)); 316 ''') 317 buildMult3InstUnCc("smultt", '''Reg0 = resTemp = 318 sext<16>(bits(Reg1, 31, 16)) * 319 sext<16>(bits(Reg2, 31, 16)); 320 ''') 321 buildMult4Inst ("smull", '''resTemp = Reg2.sw * Reg3.sw; 322 Reg0 = (int32_t)resTemp; 323 Reg1 = (int32_t)(resTemp >> 32); 324 ''', "llbit") 325 buildMult3InstUnCc("smulwb", '''Reg0 = resTemp = 326 (Reg1.sw * 327 sext<16>(bits(Reg2, 15, 0))) >> 16; 328 ''') 329 buildMult3InstUnCc("smulwt", '''Reg0 = resTemp = 330 (Reg1.sw * 331 sext<16>(bits(Reg2, 31, 16))) >> 16; 332 ''') 333 buildMult3InstUnCc("smusd", '''Reg0 = resTemp = 334 sext<16>(bits(Reg1, 15, 0)) * 335 sext<16>(bits(Reg2, 15, 0)) - 336 sext<16>(bits(Reg1, 31, 16)) * 337 sext<16>(bits(Reg2, 31, 16)); 338 ''') 339 buildMult3InstUnCc("smusdx", '''Reg0 = resTemp = 340 sext<16>(bits(Reg1, 15, 0)) * 341 sext<16>(bits(Reg2, 31, 16)) - 342 sext<16>(bits(Reg1, 31, 16)) * 343 sext<16>(bits(Reg2, 15, 0)); 344 ''') 345 buildMult4InstUnCc("umaal", '''resTemp = Reg2.ud * Reg3.ud + 346 Reg0.ud + Reg1.ud; 347 Reg0.ud = (uint32_t)resTemp; 348 Reg1.ud = (uint32_t)(resTemp >> 32); 349 ''') 350 buildMult4Inst ("umlal", '''resTemp = Reg2.ud * Reg3.ud + Reg0.ud + 351 (Reg1.ud << 32); 352 Reg0.ud = (uint32_t)resTemp; 353 Reg1.ud = (uint32_t)(resTemp >> 32); 354 ''', "llbit") 355 buildMult4Inst ("umull", '''resTemp = Reg2.ud * Reg3.ud; 356 Reg0 = (uint32_t)resTemp; 357 Reg1 = (uint32_t)(resTemp >> 32); 358 ''', "llbit") 359}}; 360