|
|
1.1 ! root 1: /* ! 2: * Helpers for integer and multimedia instructions. ! 3: * ! 4: * Copyright (c) 2007 Jocelyn Mayer ! 5: * ! 6: * This library is free software; you can redistribute it and/or ! 7: * modify it under the terms of the GNU Lesser General Public ! 8: * License as published by the Free Software Foundation; either ! 9: * version 2 of the License, or (at your option) any later version. ! 10: * ! 11: * This library is distributed in the hope that it will be useful, ! 12: * but WITHOUT ANY WARRANTY; without even the implied warranty of ! 13: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ! 14: * Lesser General Public License for more details. ! 15: * ! 16: * You should have received a copy of the GNU Lesser General Public ! 17: * License along with this library; if not, see <http://www.gnu.org/licenses/>. ! 18: */ ! 19: ! 20: #include "cpu.h" ! 21: #include "helper.h" ! 22: #include "host-utils.h" ! 23: ! 24: ! 25: uint64_t helper_umulh(uint64_t op1, uint64_t op2) ! 26: { ! 27: uint64_t tl, th; ! 28: mulu64(&tl, &th, op1, op2); ! 29: return th; ! 30: } ! 31: ! 32: uint64_t helper_ctpop(uint64_t arg) ! 33: { ! 34: return ctpop64(arg); ! 35: } ! 36: ! 37: uint64_t helper_ctlz(uint64_t arg) ! 38: { ! 39: return clz64(arg); ! 40: } ! 41: ! 42: uint64_t helper_cttz(uint64_t arg) ! 43: { ! 44: return ctz64(arg); ! 45: } ! 46: ! 47: static inline uint64_t byte_zap(uint64_t op, uint8_t mskb) ! 48: { ! 49: uint64_t mask; ! 50: ! 51: mask = 0; ! 52: mask |= ((mskb >> 0) & 1) * 0x00000000000000FFULL; ! 53: mask |= ((mskb >> 1) & 1) * 0x000000000000FF00ULL; ! 54: mask |= ((mskb >> 2) & 1) * 0x0000000000FF0000ULL; ! 55: mask |= ((mskb >> 3) & 1) * 0x00000000FF000000ULL; ! 56: mask |= ((mskb >> 4) & 1) * 0x000000FF00000000ULL; ! 57: mask |= ((mskb >> 5) & 1) * 0x0000FF0000000000ULL; ! 58: mask |= ((mskb >> 6) & 1) * 0x00FF000000000000ULL; ! 59: mask |= ((mskb >> 7) & 1) * 0xFF00000000000000ULL; ! 60: ! 61: return op & ~mask; ! 62: } ! 63: ! 64: uint64_t helper_zap(uint64_t val, uint64_t mask) ! 65: { ! 66: return byte_zap(val, mask); ! 67: } ! 68: ! 69: uint64_t helper_zapnot(uint64_t val, uint64_t mask) ! 70: { ! 71: return byte_zap(val, ~mask); ! 72: } ! 73: ! 74: uint64_t helper_cmpbge(uint64_t op1, uint64_t op2) ! 75: { ! 76: uint8_t opa, opb, res; ! 77: int i; ! 78: ! 79: res = 0; ! 80: for (i = 0; i < 8; i++) { ! 81: opa = op1 >> (i * 8); ! 82: opb = op2 >> (i * 8); ! 83: if (opa >= opb) { ! 84: res |= 1 << i; ! 85: } ! 86: } ! 87: return res; ! 88: } ! 89: ! 90: uint64_t helper_minub8(uint64_t op1, uint64_t op2) ! 91: { ! 92: uint64_t res = 0; ! 93: uint8_t opa, opb, opr; ! 94: int i; ! 95: ! 96: for (i = 0; i < 8; ++i) { ! 97: opa = op1 >> (i * 8); ! 98: opb = op2 >> (i * 8); ! 99: opr = opa < opb ? opa : opb; ! 100: res |= (uint64_t)opr << (i * 8); ! 101: } ! 102: return res; ! 103: } ! 104: ! 105: uint64_t helper_minsb8(uint64_t op1, uint64_t op2) ! 106: { ! 107: uint64_t res = 0; ! 108: int8_t opa, opb; ! 109: uint8_t opr; ! 110: int i; ! 111: ! 112: for (i = 0; i < 8; ++i) { ! 113: opa = op1 >> (i * 8); ! 114: opb = op2 >> (i * 8); ! 115: opr = opa < opb ? opa : opb; ! 116: res |= (uint64_t)opr << (i * 8); ! 117: } ! 118: return res; ! 119: } ! 120: ! 121: uint64_t helper_minuw4(uint64_t op1, uint64_t op2) ! 122: { ! 123: uint64_t res = 0; ! 124: uint16_t opa, opb, opr; ! 125: int i; ! 126: ! 127: for (i = 0; i < 4; ++i) { ! 128: opa = op1 >> (i * 16); ! 129: opb = op2 >> (i * 16); ! 130: opr = opa < opb ? opa : opb; ! 131: res |= (uint64_t)opr << (i * 16); ! 132: } ! 133: return res; ! 134: } ! 135: ! 136: uint64_t helper_minsw4(uint64_t op1, uint64_t op2) ! 137: { ! 138: uint64_t res = 0; ! 139: int16_t opa, opb; ! 140: uint16_t opr; ! 141: int i; ! 142: ! 143: for (i = 0; i < 4; ++i) { ! 144: opa = op1 >> (i * 16); ! 145: opb = op2 >> (i * 16); ! 146: opr = opa < opb ? opa : opb; ! 147: res |= (uint64_t)opr << (i * 16); ! 148: } ! 149: return res; ! 150: } ! 151: ! 152: uint64_t helper_maxub8(uint64_t op1, uint64_t op2) ! 153: { ! 154: uint64_t res = 0; ! 155: uint8_t opa, opb, opr; ! 156: int i; ! 157: ! 158: for (i = 0; i < 8; ++i) { ! 159: opa = op1 >> (i * 8); ! 160: opb = op2 >> (i * 8); ! 161: opr = opa > opb ? opa : opb; ! 162: res |= (uint64_t)opr << (i * 8); ! 163: } ! 164: return res; ! 165: } ! 166: ! 167: uint64_t helper_maxsb8(uint64_t op1, uint64_t op2) ! 168: { ! 169: uint64_t res = 0; ! 170: int8_t opa, opb; ! 171: uint8_t opr; ! 172: int i; ! 173: ! 174: for (i = 0; i < 8; ++i) { ! 175: opa = op1 >> (i * 8); ! 176: opb = op2 >> (i * 8); ! 177: opr = opa > opb ? opa : opb; ! 178: res |= (uint64_t)opr << (i * 8); ! 179: } ! 180: return res; ! 181: } ! 182: ! 183: uint64_t helper_maxuw4(uint64_t op1, uint64_t op2) ! 184: { ! 185: uint64_t res = 0; ! 186: uint16_t opa, opb, opr; ! 187: int i; ! 188: ! 189: for (i = 0; i < 4; ++i) { ! 190: opa = op1 >> (i * 16); ! 191: opb = op2 >> (i * 16); ! 192: opr = opa > opb ? opa : opb; ! 193: res |= (uint64_t)opr << (i * 16); ! 194: } ! 195: return res; ! 196: } ! 197: ! 198: uint64_t helper_maxsw4(uint64_t op1, uint64_t op2) ! 199: { ! 200: uint64_t res = 0; ! 201: int16_t opa, opb; ! 202: uint16_t opr; ! 203: int i; ! 204: ! 205: for (i = 0; i < 4; ++i) { ! 206: opa = op1 >> (i * 16); ! 207: opb = op2 >> (i * 16); ! 208: opr = opa > opb ? opa : opb; ! 209: res |= (uint64_t)opr << (i * 16); ! 210: } ! 211: return res; ! 212: } ! 213: ! 214: uint64_t helper_perr(uint64_t op1, uint64_t op2) ! 215: { ! 216: uint64_t res = 0; ! 217: uint8_t opa, opb, opr; ! 218: int i; ! 219: ! 220: for (i = 0; i < 8; ++i) { ! 221: opa = op1 >> (i * 8); ! 222: opb = op2 >> (i * 8); ! 223: if (opa >= opb) { ! 224: opr = opa - opb; ! 225: } else { ! 226: opr = opb - opa; ! 227: } ! 228: res += opr; ! 229: } ! 230: return res; ! 231: } ! 232: ! 233: uint64_t helper_pklb(uint64_t op1) ! 234: { ! 235: return (op1 & 0xff) | ((op1 >> 24) & 0xff00); ! 236: } ! 237: ! 238: uint64_t helper_pkwb(uint64_t op1) ! 239: { ! 240: return ((op1 & 0xff) ! 241: | ((op1 >> 8) & 0xff00) ! 242: | ((op1 >> 16) & 0xff0000) ! 243: | ((op1 >> 24) & 0xff000000)); ! 244: } ! 245: ! 246: uint64_t helper_unpkbl(uint64_t op1) ! 247: { ! 248: return (op1 & 0xff) | ((op1 & 0xff00) << 24); ! 249: } ! 250: ! 251: uint64_t helper_unpkbw(uint64_t op1) ! 252: { ! 253: return ((op1 & 0xff) ! 254: | ((op1 & 0xff00) << 8) ! 255: | ((op1 & 0xff0000) << 16) ! 256: | ((op1 & 0xff000000) << 24)); ! 257: } ! 258: ! 259: uint64_t helper_addqv(CPUAlphaState *env, uint64_t op1, uint64_t op2) ! 260: { ! 261: uint64_t tmp = op1; ! 262: op1 += op2; ! 263: if (unlikely((tmp ^ op2 ^ (-1ULL)) & (tmp ^ op1) & (1ULL << 63))) { ! 264: arith_excp(env, GETPC(), EXC_M_IOV, 0); ! 265: } ! 266: return op1; ! 267: } ! 268: ! 269: uint64_t helper_addlv(CPUAlphaState *env, uint64_t op1, uint64_t op2) ! 270: { ! 271: uint64_t tmp = op1; ! 272: op1 = (uint32_t)(op1 + op2); ! 273: if (unlikely((tmp ^ op2 ^ (-1UL)) & (tmp ^ op1) & (1UL << 31))) { ! 274: arith_excp(env, GETPC(), EXC_M_IOV, 0); ! 275: } ! 276: return op1; ! 277: } ! 278: ! 279: uint64_t helper_subqv(CPUAlphaState *env, uint64_t op1, uint64_t op2) ! 280: { ! 281: uint64_t res; ! 282: res = op1 - op2; ! 283: if (unlikely((op1 ^ op2) & (res ^ op1) & (1ULL << 63))) { ! 284: arith_excp(env, GETPC(), EXC_M_IOV, 0); ! 285: } ! 286: return res; ! 287: } ! 288: ! 289: uint64_t helper_sublv(CPUAlphaState *env, uint64_t op1, uint64_t op2) ! 290: { ! 291: uint32_t res; ! 292: res = op1 - op2; ! 293: if (unlikely((op1 ^ op2) & (res ^ op1) & (1UL << 31))) { ! 294: arith_excp(env, GETPC(), EXC_M_IOV, 0); ! 295: } ! 296: return res; ! 297: } ! 298: ! 299: uint64_t helper_mullv(CPUAlphaState *env, uint64_t op1, uint64_t op2) ! 300: { ! 301: int64_t res = (int64_t)op1 * (int64_t)op2; ! 302: ! 303: if (unlikely((int32_t)res != res)) { ! 304: arith_excp(env, GETPC(), EXC_M_IOV, 0); ! 305: } ! 306: return (int64_t)((int32_t)res); ! 307: } ! 308: ! 309: uint64_t helper_mulqv(CPUAlphaState *env, uint64_t op1, uint64_t op2) ! 310: { ! 311: uint64_t tl, th; ! 312: ! 313: muls64(&tl, &th, op1, op2); ! 314: /* If th != 0 && th != -1, then we had an overflow */ ! 315: if (unlikely((th + 1) > 1)) { ! 316: arith_excp(env, GETPC(), EXC_M_IOV, 0); ! 317: } ! 318: return tl; ! 319: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.