1# Copyright (c) 2007 The Hewlett-Packard Development Company 2# All rights reserved. 3# 4# The license below extends only to copyright in the software and shall 5# not be construed as granting a license to any other intellectual 6# property including but not limited to intellectual property relating 7# to a hardware implementation of the functionality of the software 8# licensed hereunder. You may use the software subject to the license 9# terms below provided that you ensure that this notice is replicated 10# unmodified and in its entirety in all distributions of the software, 11# modified or unmodified, in source code or in binary form. 12# 13# Redistribution and use in source and binary forms, with or without 14# modification, are permitted provided that the following conditions are 15# met: redistributions of source code must retain the above copyright 16# notice, this list of conditions and the following disclaimer; 17# redistributions in binary form must reproduce the above copyright 18# notice, this list of conditions and the following disclaimer in the 19# documentation and/or other materials provided with the distribution; 20# neither the name of the copyright holders nor the names of its 21# contributors may be used to endorse or promote products derived from 22# this software without specific prior written permission. 23# 24# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 25# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 26# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 27# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 28# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 29# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 30# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 31# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 32# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 33# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 34# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35# 36# Authors: Gabe Black 37 38microcode = ''' 39 40# 41# Byte version of one operand unsigned multiply. 42# 43 44def macroop MUL_B_R 45{ 46 mul1u rax, reg, flags=(OF,CF) 47 mulel rax 48 muleh ah 49}; 50 51def macroop MUL_B_M 52{ 53 ld t1, seg, sib, disp 54 mul1u rax, t1, flags=(OF,CF) 55 mulel rax 56 muleh ah 57}; 58 59def macroop MUL_B_P 60{ 61 rdip t7 62 ld t1, seg, riprel, disp 63 mul1u rax, t1, flags=(OF,CF) 64 mulel rax 65 muleh ah 66}; 67 68# 69# One operand unsigned multiply. 70# 71 72def macroop MUL_R 73{ 74 mul1u rax, reg, flags=(OF,CF) 75 mulel rax 76 muleh rdx 77}; 78 79def macroop MUL_M 80{ 81 ld t1, seg, sib, disp 82 mul1u rax, t1, flags=(OF,CF) 83 mulel rax 84 muleh rdx 85}; 86 87def macroop MUL_P 88{ 89 rdip t7 90 ld t1, seg, riprel, disp 91 mul1u rax, t1, flags=(OF,CF) 92 mulel rax 93 muleh rdx 94}; 95 96# 97# Byte version of one operand signed multiply. 98# 99 100def macroop IMUL_B_R 101{ 102 mul1s rax, reg, flags=(OF,CF) 103 mulel rax 104 muleh ah 105}; 106 107def macroop IMUL_B_M 108{ 109 ld t1, seg, sib, disp 110 mul1s rax, t1, flags=(OF,CF) 111 mulel rax 112 muleh ah 113}; 114 115def macroop IMUL_B_P 116{ 117 rdip t7 118 ld t1, seg, riprel, disp 119 mul1s rax, t1, flags=(OF,CF) 120 mulel rax 121 muleh ah 122}; 123 124# 125# One operand signed multiply. 126# 127 128def macroop IMUL_R 129{ 130 mul1s rax, reg, flags=(OF,CF) 131 mulel rax 132 muleh rdx 133}; 134 135def macroop IMUL_M 136{ 137 ld t1, seg, sib, disp 138 mul1s rax, t1, flags=(OF,CF) 139 mulel rax 140 muleh rdx 141}; 142 143def macroop IMUL_P 144{ 145 rdip t7 146 ld t1, seg, riprel, disp 147 mul1s rax, t1, flags=(OF,CF) 148 mulel rax 149 muleh rdx 150}; 151 152def macroop IMUL_R_R 153{ 154 mul1s reg, regm, flags=(OF,CF) 155 mulel reg 156 muleh t0 157}; 158 159def macroop IMUL_R_M 160{ 161 ld t1, seg, sib, disp 162 mul1s reg, t1, flags=(CF,OF) 163 mulel reg 164 muleh t0 165}; 166 167def macroop IMUL_R_P 168{ 169 rdip t7 170 ld t1, seg, riprel, disp 171 mul1s reg, t1, flags=(CF,OF) 172 mulel reg 173 muleh t0 174}; 175 176# 177# Three operand signed multiply. 178# 179 180def macroop IMUL_R_R_I 181{ 182 limm t1, imm 183 mul1s regm, t1, flags=(OF,CF) 184 mulel reg 185 muleh t0 186}; 187 188def macroop IMUL_R_M_I 189{ 190 limm t1, imm 191 ld t2, seg, sib, disp 192 mul1s t2, t1, flags=(OF,CF) 193 mulel reg 194 muleh t0 195}; 196 197def macroop IMUL_R_P_I 198{ 199 rdip t7 200 limm t1, imm 201 ld t2, seg, riprel, disp 202 mul1s t2, t1, flags=(OF,CF) 203 mulel reg 204 muleh t0 205}; 206''' 207 208pcRel = ''' 209 rdip t7 210 ld %s, seg, riprel, disp 211''' 212sibRel = ''' 213 ld %s, seg, sib, disp 214''' 215 216# 217# One byte version of unsigned division 218# 219 220divcode = ''' 221def macroop DIV_B_%(suffix)s 222{ 223 %(readOp1)s 224 # Do the initial part of the division 225 div1 ah, %(op1)s, dataSize=1 226 227 #These are split out so we can initialize the number of bits in the 228 #second register 229 div2i t1, rax, 8, dataSize=1 230 div2 t1, rax, t1, dataSize=1 231 232 #Loop until we're out of bits to shift in 233divLoopTop: 234 div2 t1, rax, t1, dataSize=1 235 div2 t1, rax, t1, flags=(EZF,), dataSize=1 236 br label("divLoopTop"), flags=(nCEZF,) 237 238 #Unload the answer 239 divq rax, dataSize=1 240 divr ah, dataSize=1 241}; 242''' 243 244# 245# Unsigned division 246# 247 248divcode += ''' 249def macroop DIV_%(suffix)s 250{ 251 %(readOp1)s 252 # Do the initial part of the division 253 div1 rdx, %(op1)s 254 255 #These are split out so we can initialize the number of bits in the 256 #second register 257 div2i t1, rax, "env.dataSize * 8" 258 div2 t1, rax, t1 259 260 #Loop until we're out of bits to shift in 261 #The amount of unrolling here could stand some tuning 262divLoopTop: 263 div2 t1, rax, t1 264 div2 t1, rax, t1 265 div2 t1, rax, t1 266 div2 t1, rax, t1, flags=(EZF,) 267 br label("divLoopTop"), flags=(nCEZF,) 268 269 #Unload the answer 270 divq rax 271 divr rdx 272}; 273''' 274 275# 276# One byte version of signed division 277# 278 279divcode += ''' 280def macroop IDIV_B_%(suffix)s 281{ 282 # Negate dividend 283 sub t1, t0, rax, flags=(ECF,), dataSize=1 284 ruflag t4, 3 285 sub t2, t0, ah, dataSize=1 286 sub t2, t2, t4 287 288 %(readOp1)s 289 290 #Find the sign of the divisor 291 slli t0, %(op1)s, 1, flags=(ECF,), dataSize=1 292 293 # Negate divisor 294 sub t3, t0, %(op1)s, dataSize=1 295 # Put the divisor's absolute value into t3 296 mov t3, t3, %(op1)s, flags=(nCECF,), dataSize=1 297 298 #Find the sign of the dividend 299 slli t0, ah, 1, flags=(ECF,), dataSize=1 300 301 # Put the dividend's absolute value into t1 and t2 302 mov t1, t1, rax, flags=(nCECF,), dataSize=1 303 mov t2, t2, ah, flags=(nCECF,), dataSize=1 304 305 # Do the initial part of the division 306 div1 t2, t3, dataSize=1 307 308 #These are split out so we can initialize the number of bits in the 309 #second register 310 div2i t4, t1, 8, dataSize=1 311 div2 t4, t1, t4, dataSize=1 312 313 #Loop until we're out of bits to shift in 314divLoopTop: 315 div2 t4, t1, t4, dataSize=1 316 div2 t4, t1, t4, flags=(EZF,), dataSize=1 317 br label("divLoopTop"), flags=(nCEZF,) 318 319 #Unload the answer 320 divq t5, dataSize=1 321 divr t6, dataSize=1 322 323 # Fix up signs. The sign of the dividend is still lying around in ECF. 324 # The sign of the remainder, ah, is the same as the dividend. The sign 325 # of the quotient is negated if the signs of the divisor and dividend 326 # were different. 327 328 # Negate the remainder 329 sub t4, t0, t6, dataSize=1 330 # If the dividend was negitive, put the negated remainder in ah. 331 mov ah, ah, t4, (CECF,), dataSize=1 332 # Otherwise put the regular remainder in ah. 333 mov ah, ah, t6, (nCECF,), dataSize=1 334 335 # Negate the quotient. 336 sub t4, t0, t5, dataSize=1 337 # If the dividend was negative, start using the negated quotient 338 mov t5, t5, t4, (CECF,), dataSize=1 339 340 # Check the sign of the divisor 341 slli t0, %(op1)s, 1, flags=(ECF,), dataSize=1 342 343 # Negate the (possibly already negated) quotient 344 sub t4, t0, t5, dataSize=1 345 # If the divisor was negative, put the negated quotient in rax. 346 mov rax, rax, t4, (CECF,), dataSize=1 347 # Otherwise put the one that wasn't negated (at least here) in rax. 348 mov rax, rax, t5, (nCECF,), dataSize=1 349}; 350''' 351 352# 353# Signed division 354# 355 356divcode += ''' 357def macroop IDIV_%(suffix)s 358{ 359 # Negate dividend 360 sub t1, t0, rax, flags=(ECF,) 361 ruflag t4, 3 362 sub t2, t0, rdx 363 sub t2, t2, t4 364 365 %(readOp1)s 366 367 #Find the sign of the divisor 368 slli t0, %(op1)s, 1, flags=(ECF,) 369 370 # Negate divisor 371 sub t3, t0, %(op1)s 372 # Put the divisor's absolute value into t3 373 mov t3, t3, %(op1)s, flags=(nCECF,) 374 375 #Find the sign of the dividend 376 slli t0, rdx, 1, flags=(ECF,) 377 378 # Put the dividend's absolute value into t1 and t2 379 mov t1, t1, rax, flags=(nCECF,) 380 mov t2, t2, rdx, flags=(nCECF,) 381 382 # Do the initial part of the division 383 div1 t2, t3 384 385 #These are split out so we can initialize the number of bits in the 386 #second register 387 div2i t4, t1, "env.dataSize * 8" 388 div2 t4, t1, t4 389 390 #Loop until we're out of bits to shift in 391divLoopTop: 392 div2 t4, t1, t4 393 div2 t4, t1, t4 394 div2 t4, t1, t4 395 div2 t4, t1, t4, flags=(EZF,) 396 br label("divLoopTop"), flags=(nCEZF,) 397 398 #Unload the answer 399 divq t5 400 divr t6 401 402 # Fix up signs. The sign of the dividend is still lying around in ECF. 403 # The sign of the remainder, ah, is the same as the dividend. The sign 404 # of the quotient is negated if the signs of the divisor and dividend 405 # were different. 406 407 # Negate the remainder 408 sub t4, t0, t6 409 # If the dividend was negitive, put the negated remainder in rdx. 410 mov rdx, rdx, t4, (CECF,) 411 # Otherwise put the regular remainder in rdx. 412 mov rdx, rdx, t6, (nCECF,) 413 414 # Negate the quotient. 415 sub t4, t0, t5 416 # If the dividend was negative, start using the negated quotient 417 mov t5, t5, t4, (CECF,) 418 419 # Check the sign of the divisor 420 slli t0, %(op1)s, 1, flags=(ECF,) 421 422 # Negate the (possibly already negated) quotient 423 sub t4, t0, t5 424 # If the divisor was negative, put the negated quotient in rax. 425 mov rax, rax, t4, (CECF,) 426 # Otherwise put the one that wasn't negated (at least here) in rax. 427 mov rax, rax, t5, (nCECF,) 428}; 429''' 430 431microcode += divcode % {"suffix": "R", 432 "readOp1": "", "op1": "reg"} 433microcode += divcode % {"suffix": "M", 434 "readOp1": sibRel % "t2", "op1": "t2"} 435microcode += divcode % {"suffix": "P", 436 "readOp1": pcRel % "t2", "op1": "t2"} 437