Open64 (mfef90, whirl2f, and IR tools)
TAG: version-openad; SVN changeset: 916
|
00001 /* 00002 00003 Copyright (C) 2000, 2001 Silicon Graphics, Inc. All Rights Reserved. 00004 00005 This program is free software; you can redistribute it and/or modify it 00006 under the terms of version 2 of the GNU General Public License as 00007 published by the Free Software Foundation. 00008 00009 This program is distributed in the hope that it would be useful, but 00010 WITHOUT ANY WARRANTY; without even the implied warranty of 00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 00012 00013 Further, this software is distributed without any warranty that it is 00014 free of the rightful claim of any third person regarding infringement 00015 or the like. Any license provided herein, whether implied or 00016 otherwise, applies only to this software file. Patent licenses, if 00017 any, provided herein do not apply to combinations of this program with 00018 other software, or any other product whatsoever. 00019 00020 You should have received a copy of the GNU General Public License along 00021 with this program; if not, write the Free Software Foundation, Inc., 59 00022 Temple Place - Suite 330, Boston MA 02111-1307, USA. 00023 00024 Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pky, 00025 Mountain View, CA 94043, or: 00026 00027 http://www.sgi.com 00028 00029 For further information regarding this notice, see: 00030 00031 http://oss.sgi.com/projects/GenInfo/NoticeExplan 00032 00033 */ 00034 00035 00036 /* Bitwise operations */ 00037 00038 #include "arith.internal.h" 00039 00040 #define bitoper(name,opr) \ 00041 int \ 00042 name (AR_DATA *res, const AR_TYPE *resulttype, \ 00043 const AR_DATA *op1, const AR_TYPE *opnd1type, \ 00044 const AR_DATA *op2, const AR_TYPE *opnd2type) { \ 00045 ar_data* result = (ar_data*)res; \ 00046 ar_data* opnd1 = (ar_data*)op1; \ 00047 ar_data* opnd2 = (ar_data*)op2; \ 00048 \ 00049 if (*opnd1type != *resulttype || \ 00050 *opnd2type != *resulttype || \ 00051 AR_CLASS (*resulttype) != AR_CLASS_INT) \ 00052 return (AR_STAT_INVALID_TYPE); \ 00053 \ 00054 switch (AR_INT_SIZE (*opnd1type)) { \ 00055 case AR_INT_SIZE_8: \ 00056 ZERO_INT8_UPPER(result); \ 00057 result->ar_i8.part5 = opnd1->ar_i8.part5 opr \ 00058 opnd2->ar_i8.part5; \ 00059 break; \ 00060 \ 00061 case AR_INT_SIZE_16: \ 00062 ZERO_INT16_UPPER(result); \ 00063 result->ar_i64.part4 = opnd1->ar_i64.part4 opr \ 00064 opnd2->ar_i64.part4; \ 00065 break; \ 00066 \ 00067 case AR_INT_SIZE_32: \ 00068 ZERO_INT32_UPPER(result); \ 00069 result->ar_i64.part3 = opnd1->ar_i64.part3 opr \ 00070 opnd2->ar_i64.part3; \ 00071 result->ar_i64.part4 = opnd1->ar_i64.part4 opr \ 00072 opnd2->ar_i64.part4; \ 00073 break; \ 00074 \ 00075 case AR_INT_SIZE_46: \ 00076 case AR_INT_SIZE_64: \ 00077 result->ar_i64.part1 = opnd1->ar_i64.part1 opr \ 00078 opnd2->ar_i64.part1; \ 00079 result->ar_i64.part2 = opnd1->ar_i64.part2 opr \ 00080 opnd2->ar_i64.part2; \ 00081 result->ar_i64.part3 = opnd1->ar_i64.part3 opr \ 00082 opnd2->ar_i64.part3; \ 00083 result->ar_i64.part4 = opnd1->ar_i64.part4 opr \ 00084 opnd2->ar_i64.part4; \ 00085 break; \ 00086 \ 00087 default: \ 00088 return (AR_STAT_INVALID_TYPE); \ 00089 } \ 00090 \ 00091 return AR_status ((AR_DATA*)result, resulttype); \ 00092 } 00093 00094 bitoper (AR_bitor, |) 00095 bitoper (AR_bitand, &) 00096 bitoper (AR_bitxor, ^) 00097 00098 #undef bitoper 00099 00100 00101 int 00102 AR_bitcomplement (AR_DATA *res, const AR_TYPE *resulttype, 00103 const AR_DATA *op1, const AR_TYPE *opnd1type) { 00104 ar_data* result = (ar_data*)res; 00105 ar_data* opnd1 = (ar_data*)op1; 00106 00107 if (*resulttype != *opnd1type || 00108 AR_CLASS (*resulttype) != AR_CLASS_INT) 00109 return (AR_STAT_INVALID_TYPE); 00110 00111 switch (AR_INT_SIZE (*opnd1type)) { 00112 case AR_INT_SIZE_8: 00113 result->ar_i8.part5 = ~opnd1->ar_i8.part5; 00114 break; 00115 00116 case AR_INT_SIZE_16: 00117 result->ar_i64.part4 = ~opnd1->ar_i64.part4; 00118 break; 00119 00120 case AR_INT_SIZE_32: 00121 result->ar_i64.part3 = ~opnd1->ar_i64.part3; 00122 result->ar_i64.part4 = ~opnd1->ar_i64.part4; 00123 break; 00124 00125 case AR_INT_SIZE_46: 00126 case AR_INT_SIZE_64: 00127 result->ar_i64.part1 = ~opnd1->ar_i64.part1; 00128 result->ar_i64.part2 = ~opnd1->ar_i64.part2; 00129 result->ar_i64.part3 = ~opnd1->ar_i64.part3; 00130 result->ar_i64.part4 = ~opnd1->ar_i64.part4; 00131 break; 00132 00133 default: 00134 return (AR_STAT_INVALID_TYPE); 00135 } 00136 00137 return AR_status ((AR_DATA*)result, resulttype); 00138 } 00139 00140 00141 /* Perform a right circular shift of (opnd1,opnd2) and return the 00142 * rightmost AR_INT_SIZE bits of the result. 00143 */ 00144 void 00145 ar_dblshift (ar_data *result, const AR_TYPE *resulttype, 00146 const ar_data *opnd1, 00147 const ar_data *opnd2, 00148 int shiftcount) { 00149 00150 int i, sc, lsc; 00151 unsigned int chunk [8]; 00152 00153 switch (AR_INT_SIZE (*resulttype)) { 00154 case AR_INT_SIZE_8: 00155 if (shiftcount < 0 || shiftcount > 16) 00156 ar_internal_error (2000, __FILE__, __LINE__); 00157 00158 /* Split the 16-bit concatenated argument into two chunks of 00159 * eight bits, and perform the shift (mod 8) on the chunks. 00160 */ 00161 sc = shiftcount % 8; 00162 lsc = 8 - sc; 00163 chunk [0] = (opnd1->ar_i8.part5 >> sc) | 00164 (opnd2->ar_i8.part5 << lsc); 00165 chunk [1] = (opnd2->ar_i8.part5 >> sc) | 00166 (opnd1->ar_i8.part5 << lsc); 00167 00168 /* Complete the shift by moving the chunk corresponding to the 00169 * rightmost 8 bits into the result. 00170 */ 00171 sc = 2 - (shiftcount / 8); 00172 sc += 1; /* get rightmost chunk */ 00173 00174 ZERO_INT8_UPPER(result); 00175 result->ar_i8.part5 = chunk [sc % 2] & 0xFF; 00176 break; 00177 00178 case AR_INT_SIZE_16: 00179 if (shiftcount < 0 || shiftcount > 32) 00180 ar_internal_error (2000, __FILE__, __LINE__); 00181 00182 /* Split the 32-bit concatenated argument into two chunks of 00183 * sixteen bits, and perform the shift (mod 16) on the chunks. 00184 */ 00185 sc = shiftcount % 16; 00186 lsc = 16 - sc; 00187 chunk [0] = (opnd1->ar_i64.part4 >> sc) | 00188 (opnd2->ar_i64.part4 << lsc); 00189 chunk [1] = (opnd2->ar_i64.part4 >> sc) | 00190 (opnd1->ar_i64.part4 << lsc); 00191 00192 /* Complete the shift by moving the chunk corresponding to the 00193 * rightmost 16 bits into the result. 00194 */ 00195 sc = 2 - (shiftcount / 16); 00196 sc += 1; /* get rightmost chunk */ 00197 00198 ZERO_INT16_UPPER(result); 00199 result->ar_i64.part4 = chunk [sc % 2] & 0xFFFF; 00200 break; 00201 00202 case AR_INT_SIZE_32: 00203 if (shiftcount < 0 || shiftcount > 64) 00204 ar_internal_error (2000, __FILE__, __LINE__); 00205 00206 /* Split the 64-bit concatenated argument into four chunks of 00207 * sixteen bits, and perform the shift (mod 16) on the chunks. 00208 */ 00209 sc = shiftcount % 16; 00210 lsc = 16 - sc; 00211 chunk [0] = (opnd1->ar_i64.part3 >> sc) | 00212 (opnd2->ar_i64.part4 << lsc); 00213 chunk [1] = (opnd1->ar_i64.part4 >> sc) | 00214 (opnd1->ar_i64.part3 << lsc); 00215 chunk [2] = (opnd2->ar_i64.part3 >> sc) | 00216 (opnd1->ar_i64.part4 << lsc); 00217 chunk [3] = (opnd2->ar_i64.part4 >> sc) | 00218 (opnd2->ar_i64.part3 << lsc); 00219 00220 /* Complete the shift by moving the chunks corresponding to the 00221 * rightmost 32 bits into the result. 00222 */ 00223 sc = 4 - (shiftcount / 16); 00224 sc += 2; /* get rightmost 2 chunks */ 00225 00226 ZERO_INT32_UPPER(result); 00227 result->ar_i64.part3 = chunk [sc++ % 4] & 0xFFFF; 00228 result->ar_i64.part4 = chunk [sc % 4] & 0xFFFF; 00229 break; 00230 00231 case AR_INT_SIZE_46: 00232 case AR_INT_SIZE_64: 00233 if (shiftcount < 0 || shiftcount > 128) 00234 ar_internal_error (2000, __FILE__, __LINE__); 00235 00236 /* Split the 128-bit concatenated argument into eight chunks of 00237 * sixteen bits, and perform the shift (mod 16) on the chunks. 00238 */ 00239 sc = shiftcount % 16; 00240 lsc = 16 - sc; 00241 chunk [0] = (opnd1->ar_i64.part1 >> sc) | 00242 (opnd2->ar_i64.part4 << lsc); 00243 chunk [1] = (opnd1->ar_i64.part2 >> sc) | 00244 (opnd1->ar_i64.part1 << lsc); 00245 chunk [2] = (opnd1->ar_i64.part3 >> sc) | 00246 (opnd1->ar_i64.part2 << lsc); 00247 chunk [3] = (opnd1->ar_i64.part4 >> sc) | 00248 (opnd1->ar_i64.part3 << lsc); 00249 chunk [4] = (opnd2->ar_i64.part1 >> sc) | 00250 (opnd1->ar_i64.part4 << lsc); 00251 chunk [5] = (opnd2->ar_i64.part2 >> sc) | 00252 (opnd2->ar_i64.part1 << lsc); 00253 chunk [6] = (opnd2->ar_i64.part3 >> sc) | 00254 (opnd2->ar_i64.part2 << lsc); 00255 chunk [7] = (opnd2->ar_i64.part4 >> sc) | 00256 (opnd2->ar_i64.part3 << lsc); 00257 00258 /* Complete the shift by moving the chunks corresponding to the 00259 * rightmost 64 bits into the result. 00260 */ 00261 sc = 8 - (shiftcount / 16); 00262 sc += 4; /* get rightmost 4 chunks */ 00263 00264 result->ar_i64.part1 = chunk [sc++ % 8] & 0xFFFF; 00265 result->ar_i64.part2 = chunk [sc++ % 8] & 0xFFFF; 00266 result->ar_i64.part3 = chunk [sc++ % 8] & 0xFFFF; 00267 result->ar_i64.part4 = chunk [sc % 8] & 0xFFFF; 00268 break; 00269 } 00270 } 00271 00272 00273 int 00274 AR_dshiftl (AR_DATA *res, const AR_TYPE *resulttype, 00275 const AR_DATA *op1, const AR_TYPE *opnd1type, 00276 const AR_DATA *op2, const AR_TYPE *opnd2type, 00277 const AR_DATA *cnt, const AR_TYPE *counttype) { 00278 ar_data* result = (ar_data*)res; 00279 ar_data* opnd1 = (ar_data*)op1; 00280 ar_data* opnd2 = (ar_data*)op2; 00281 ar_data* count = (ar_data*)cnt; 00282 00283 if (*resulttype != *opnd1type || 00284 *resulttype != *opnd2type || 00285 AR_CLASS (*resulttype) != AR_CLASS_INT || 00286 AR_CLASS (*counttype) != AR_CLASS_INT) 00287 return AR_STAT_INVALID_TYPE; 00288 00289 switch (AR_INT_SIZE (*resulttype)) { 00290 case AR_INT_SIZE_8: 00291 /* Check for shift count not in [0,8] */ 00292 if (count->ar_i8.part5 > 8) { 00293 ZERO_INT8(result); 00294 return AR_STAT_UNDEFINED; 00295 } 00296 00297 /* Use general circular shifter */ 00298 ar_dblshift (result, resulttype, 00299 opnd2, opnd1, 16 - count->ar_i8.part5); 00300 break; 00301 00302 case AR_INT_SIZE_16: 00303 /* Check for shift count not in [0,16] */ 00304 if (count->ar_i64.part4 > 16) { 00305 ZERO_INT16(result); 00306 return AR_STAT_UNDEFINED; 00307 } 00308 00309 /* Use general circular shifter */ 00310 ar_dblshift (result, resulttype, 00311 opnd2, opnd1, 32 - count->ar_i64.part4); 00312 break; 00313 00314 case AR_INT_SIZE_32: 00315 /* Check for shift count not in [0,32] */ 00316 if (count->ar_i64.part3 || count->ar_i64.part4 > 32) { 00317 ZERO_INT32(result); 00318 return AR_STAT_UNDEFINED; 00319 } 00320 00321 /* Use general circular shifter */ 00322 ar_dblshift (result, resulttype, 00323 opnd2, opnd1, 64 - count->ar_i64.part4); 00324 break; 00325 00326 case AR_INT_SIZE_46: 00327 case AR_INT_SIZE_64: 00328 /* Check for shift count not in [0,64] */ 00329 if (count->ar_i64.part1 | count->ar_i64.part2 | 00330 count->ar_i64.part3 || count->ar_i64.part4 > 64) { 00331 ZERO_INT64(result); 00332 return AR_STAT_UNDEFINED; 00333 } 00334 00335 /* Use general circular shifter */ 00336 ar_dblshift (result, resulttype, 00337 opnd2, opnd1, 128 - count->ar_i64.part4); 00338 break; 00339 00340 default: 00341 return AR_STAT_INVALID_TYPE; 00342 } 00343 00344 return AR_status ((AR_DATA*)result, resulttype); 00345 } 00346 00347 00348 int 00349 AR_dshiftr (AR_DATA *res, const AR_TYPE *resulttype, 00350 const AR_DATA *op1, const AR_TYPE *opnd1type, 00351 const AR_DATA *op2, const AR_TYPE *opnd2type, 00352 const AR_DATA *cnt, const AR_TYPE *counttype) { 00353 ar_data* result = (ar_data*)res; 00354 ar_data* opnd1 = (ar_data*)op1; 00355 ar_data* opnd2 = (ar_data*)op2; 00356 ar_data* count = (ar_data*)cnt; 00357 00358 if (*resulttype != *opnd1type || 00359 *resulttype != *opnd2type || 00360 AR_CLASS (*resulttype) != AR_CLASS_INT || 00361 AR_CLASS (*counttype) != AR_CLASS_INT) 00362 return AR_STAT_INVALID_TYPE; 00363 00364 switch (AR_INT_SIZE (*resulttype)) { 00365 case AR_INT_SIZE_8: 00366 /* Check for shift count not in [0,8] */ 00367 if (count->ar_i8.part5 > 8) { 00368 ZERO_INT8(result); 00369 return AR_STAT_UNDEFINED; 00370 } 00371 00372 /* Use general circular shifter */ 00373 ar_dblshift (result, resulttype, 00374 opnd1, opnd2, count->ar_i8.part5); 00375 break; 00376 00377 case AR_INT_SIZE_16: 00378 /* Check for shift count not in [0,16] */ 00379 if (count->ar_i64.part4 > 16) { 00380 ZERO_INT16(result); 00381 return AR_STAT_UNDEFINED; 00382 } 00383 00384 /* Use general circular shifter */ 00385 ar_dblshift (result, resulttype, 00386 opnd1, opnd2, count->ar_i64.part4); 00387 break; 00388 00389 case AR_INT_SIZE_32: 00390 /* Check for shift count not in [0,32] */ 00391 if (count->ar_i64.part3 || count->ar_i64.part4 > 32) { 00392 ZERO_INT32(result); 00393 return AR_STAT_UNDEFINED; 00394 } 00395 00396 /* Use general circular shifter */ 00397 ar_dblshift (result, resulttype, 00398 opnd1, opnd2, count->ar_i64.part4); 00399 break; 00400 00401 case AR_INT_SIZE_46: 00402 case AR_INT_SIZE_64: 00403 /* Check for shift count not in [0,64] */ 00404 if (count->ar_i64.part1 | count->ar_i64.part2 | 00405 count->ar_i64.part3 || count->ar_i64.part4 > 64) { 00406 ZERO_INT64(result); 00407 return AR_STAT_UNDEFINED; 00408 } 00409 00410 /* Use general circular shifter */ 00411 ar_dblshift (result, resulttype, 00412 opnd1, opnd2, count->ar_i64.part4); 00413 break; 00414 00415 default: 00416 return AR_STAT_INVALID_TYPE; 00417 } 00418 00419 return AR_status ((AR_DATA*)result, resulttype); 00420 } 00421 00422 00423 int 00424 AR_shiftl (AR_DATA *res, const AR_TYPE *resulttype, 00425 const AR_DATA *opd, const AR_TYPE *opndtype, 00426 const AR_DATA *cnt, const AR_TYPE *counttype) { 00427 ar_data* result = (ar_data*)res; 00428 ar_data* opnd = (ar_data*)opd; 00429 ar_data* count = (ar_data*)cnt; 00430 00431 ar_data signextend; 00432 00433 if (*resulttype != *opndtype || 00434 AR_CLASS (*resulttype) != AR_CLASS_INT || 00435 AR_CLASS (*counttype) != AR_CLASS_INT) 00436 return AR_STAT_INVALID_TYPE; 00437 00438 switch (AR_INT_SIZE (*opndtype)) { 00439 case AR_INT_SIZE_8: 00440 /* Check for shift count not in [0,7] */ 00441 if (count->ar_i8.part5 > 7) { 00442 ZERO_INT8(result); 00443 return AR_STAT_UNDEFINED; 00444 } 00445 00446 ZERO_INT8(&signextend); 00447 00448 /* Use general circular shifter */ 00449 ar_dblshift (result, resulttype, 00450 &signextend, opnd, 16 - count->ar_i8.part5); 00451 break; 00452 00453 case AR_INT_SIZE_16: 00454 /* Check for shift count not in [0,15] */ 00455 if (count->ar_i64.part4 > 15) { 00456 ZERO_INT16(result); 00457 return AR_STAT_UNDEFINED; 00458 } 00459 00460 ZERO_INT16(&signextend); 00461 00462 /* Use general circular shifter */ 00463 ar_dblshift (result, resulttype, 00464 &signextend, opnd, 32 - count->ar_i64.part4); 00465 break; 00466 00467 case AR_INT_SIZE_32: 00468 /* Check for shift count not in [0,31] */ 00469 if (count->ar_i64.part3 || count->ar_i64.part4 > 31) { 00470 ZERO_INT32(result); 00471 return AR_STAT_UNDEFINED; 00472 } 00473 00474 ZERO_INT32(&signextend); 00475 00476 /* Use general circular shifter */ 00477 ar_dblshift (result, resulttype, 00478 &signextend, opnd, 64 - count->ar_i64.part4); 00479 break; 00480 00481 case AR_INT_SIZE_46: 00482 case AR_INT_SIZE_64: 00483 /* Check for shift count not in [0,63] */ 00484 if (count->ar_i64.part1 | count->ar_i64.part2 | 00485 count->ar_i64.part3 || count->ar_i64.part4 > 63) { 00486 ZERO_INT64(result); 00487 return AR_STAT_UNDEFINED; 00488 } 00489 00490 ZERO_INT64(&signextend); 00491 00492 /* Use general circular shifter */ 00493 ar_dblshift (result, resulttype, 00494 &signextend, opnd, 128 - count->ar_i64.part4); 00495 break; 00496 00497 default: 00498 return (AR_STAT_INVALID_TYPE); 00499 } 00500 00501 return AR_status ((AR_DATA*)result, resulttype); 00502 } 00503 00504 00505 int 00506 AR_shiftr (AR_DATA *res, const AR_TYPE *resulttype, 00507 const AR_DATA *opd, const AR_TYPE *opndtype, 00508 const AR_DATA *cnt, const AR_TYPE *counttype) { 00509 ar_data* result = (ar_data*)res; 00510 ar_data* opnd = (ar_data*)opd; 00511 ar_data* count = (ar_data*)cnt; 00512 00513 int neg; 00514 ar_data signextend; 00515 00516 if (*resulttype != *opndtype || 00517 AR_CLASS (*resulttype) != AR_CLASS_INT || 00518 AR_CLASS (*counttype) != AR_CLASS_INT) 00519 return AR_STAT_INVALID_TYPE; 00520 00521 switch (AR_INT_SIZE (*opndtype)) { 00522 case AR_INT_SIZE_8: 00523 /* Check for shift count not in [0,7] */ 00524 if (count->ar_i8.part5 > 7) { 00525 ZERO_INT8(result); 00526 return AR_STAT_UNDEFINED; 00527 } 00528 00529 if (AR_SIGNEDNESS (*resulttype) == AR_UNSIGNED) { 00530 ZERO_INT8(&signextend); 00531 } else { 00532 neg = opnd->ar_i8.part5 >> 7; 00533 signextend.ar_i8.part5 = 0xFF & -neg; 00534 } 00535 00536 /* Use general circular shifter */ 00537 ar_dblshift (result, resulttype, 00538 &signextend, opnd, count->ar_i8.part5); 00539 break; 00540 00541 case AR_INT_SIZE_16: 00542 /* Check for shift count not in [0,15] */ 00543 if (count->ar_i64.part4 > 15) { 00544 ZERO_INT16(result); 00545 return AR_STAT_UNDEFINED; 00546 } 00547 00548 if (AR_SIGNEDNESS (*resulttype) == AR_UNSIGNED) { 00549 ZERO_INT16(&signextend); 00550 } else { 00551 neg = opnd->ar_i64.part4 >> 15; 00552 signextend.ar_i64.part4 = 0xFFFF & -neg; 00553 } 00554 00555 /* Use general circular shifter */ 00556 ar_dblshift (result, resulttype, 00557 &signextend, opnd, count->ar_i64.part4); 00558 break; 00559 00560 case AR_INT_SIZE_32: 00561 /* Check for shift count not in [0,31] */ 00562 if (count->ar_i64.part3 || count->ar_i64.part4 > 31) { 00563 ZERO_INT32(result); 00564 return AR_STAT_UNDEFINED; 00565 } 00566 00567 if (AR_SIGNEDNESS (*resulttype) == AR_UNSIGNED) { 00568 ZERO_INT32(&signextend); 00569 } else { 00570 neg = opnd->ar_i64.part3 >> 15; 00571 signextend.ar_i64.part3 = 0xFFFF & -neg; 00572 signextend.ar_i64.part4 = 0xFFFF & -neg; 00573 } 00574 00575 /* Use general circular shifter */ 00576 ar_dblshift (result, resulttype, 00577 &signextend, opnd, count->ar_i64.part4); 00578 break; 00579 00580 case AR_INT_SIZE_46: 00581 case AR_INT_SIZE_64: 00582 /* Check for shift count not in [0,63] */ 00583 if (count->ar_i64.part1 | count->ar_i64.part2 | 00584 count->ar_i64.part3 || count->ar_i64.part4 > 63) { 00585 ZERO_INT64(result); 00586 return AR_STAT_UNDEFINED; 00587 } 00588 00589 if (AR_SIGNEDNESS (*resulttype) == AR_UNSIGNED) { 00590 ZERO_INT64(&signextend); 00591 } else { 00592 neg = opnd->ar_i64.part1 >> 15; 00593 signextend.ar_i64.part1 = 0xFFFF & -neg; 00594 signextend.ar_i64.part2 = 0xFFFF & -neg; 00595 signextend.ar_i64.part3 = 0xFFFF & -neg; 00596 signextend.ar_i64.part4 = 0xFFFF & -neg; 00597 } 00598 00599 /* Use general circular shifter */ 00600 ar_dblshift (result, resulttype, 00601 &signextend, opnd, count->ar_i64.part4); 00602 break; 00603 00604 default: 00605 return (AR_STAT_INVALID_TYPE); 00606 } 00607 00608 return AR_status ((AR_DATA*)result, resulttype); 00609 } 00610 00611 00612 int 00613 AR_ishft (AR_DATA *res, const AR_TYPE *resulttype, 00614 const AR_DATA *opd, const AR_TYPE *opndtype, 00615 const AR_DATA *shft, const AR_TYPE *shifttype) { 00616 ar_data *result = (ar_data*)res; 00617 ar_data *opnd = (ar_data*)opd; 00618 ar_data *shift = (ar_data*)shft; 00619 00620 AR_HOST_SINT64 shift_count; 00621 int is_right_shift; 00622 00623 ar_data zeros = { 0x0000, 0x0000, 0x0000, 0x0000 }; 00624 00625 if (*resulttype != *opndtype || 00626 AR_CLASS (*resulttype) != AR_CLASS_INT || 00627 AR_CLASS (*shifttype) != AR_CLASS_INT || 00628 AR_INT_SIZE(*opndtype) == AR_INT_SIZE_24 || 00629 AR_INT_SIZE(*shifttype) == AR_INT_SIZE_24) 00630 return AR_STAT_INVALID_TYPE; 00631 00632 ZERO_INT64(result); 00633 00634 switch (AR_INT_SIZE (*opndtype)) { 00635 case AR_INT_SIZE_8: 00636 /* 00637 * Shift has to be in [1,8]. 00638 */ 00639 INT8_TO_HOST_SINT64(shift_count, shift); 00640 if (shift_count >= 0) 00641 is_right_shift = 0; 00642 else { 00643 is_right_shift = 1; 00644 shift_count = -shift_count; 00645 } 00646 00647 if (shift_count < 0 || shift_count > 8) 00648 return AR_STAT_UNDEFINED; 00649 00650 if (is_right_shift) 00651 ar_dblshift (result, resulttype, 00652 &zeros, opnd, 00653 (int) shift_count); 00654 else 00655 ar_dblshift (result, resulttype, 00656 &zeros, opnd, 00657 (16 - (int) shift_count)); 00658 break; 00659 00660 case AR_INT_SIZE_16: 00661 /* 00662 * Shift has to be in [1,16]. 00663 */ 00664 INT16_TO_HOST_SINT64(shift_count, shift); 00665 if (shift_count >= 0) 00666 is_right_shift = 0; 00667 else { 00668 is_right_shift = 1; 00669 shift_count = -shift_count; 00670 } 00671 00672 if (shift_count < 0 || shift_count > 16) 00673 return AR_STAT_UNDEFINED; 00674 00675 if (is_right_shift) 00676 ar_dblshift (result, resulttype, 00677 &zeros, opnd, 00678 (int) shift_count); 00679 else 00680 ar_dblshift (result, resulttype, 00681 &zeros, opnd, 00682 (32 - (int) shift_count)); 00683 break; 00684 00685 case AR_INT_SIZE_32: 00686 /* 00687 * Shift has to be in [1,32]. 00688 */ 00689 INT32_TO_HOST_SINT64(shift_count, shift); 00690 if (shift_count >= 0) 00691 is_right_shift = 0; 00692 else { 00693 is_right_shift = 1; 00694 shift_count = -shift_count; 00695 } 00696 00697 if (shift_count < 0 || shift_count > 32) 00698 return AR_STAT_UNDEFINED; 00699 00700 if (is_right_shift) 00701 ar_dblshift (result, resulttype, 00702 &zeros, opnd, 00703 (int) shift_count); 00704 else 00705 ar_dblshift (result, resulttype, 00706 &zeros, opnd, 00707 (64 - (int) shift_count)); 00708 break; 00709 00710 case AR_INT_SIZE_46: 00711 case AR_INT_SIZE_64: 00712 /* 00713 * Shift has to be in [1,64]. 00714 */ 00715 INT64_TO_HOST_SINT64(shift_count, shift); 00716 if (shift_count >= 0) 00717 is_right_shift = 0; 00718 else { 00719 is_right_shift = 1; 00720 shift_count = -shift_count; 00721 } 00722 00723 if (shift_count < 0 || shift_count > 64) 00724 return AR_STAT_UNDEFINED; 00725 00726 if (is_right_shift) 00727 ar_dblshift (result, resulttype, 00728 &zeros, opnd, 00729 (int) shift_count); 00730 else 00731 ar_dblshift (result, resulttype, 00732 &zeros, opnd, 00733 (128 - (int) shift_count)); 00734 break; 00735 00736 default: 00737 return (AR_STAT_INVALID_TYPE); 00738 } 00739 00740 return AR_status ((AR_DATA*)result, resulttype); 00741 } 00742 00743 00744 int 00745 AR_ishftc (AR_DATA *res, const AR_TYPE *resulttype, 00746 const AR_DATA *opd, const AR_TYPE *opndtype, 00747 const AR_DATA *shft, const AR_TYPE *shifttype, 00748 const AR_DATA *sz, const AR_TYPE *sizetype) { 00749 ar_data *result = (ar_data*)res; 00750 ar_data *opnd = (ar_data*)opd; 00751 ar_data *shift = (ar_data*)shft; 00752 ar_data *size = (ar_data*)sz; 00753 00754 AR_HOST_SINT64 shift_count; 00755 AR_HOST_SINT64 shift_size; 00756 int type_size; 00757 00758 ar_data ones8 = { 0x0000, 0x0000, 0x0000, 0x00FF }; 00759 ar_data ones16 = { 0x0000, 0x0000, 0x0000, 0xFFFF }; 00760 ar_data ones32 = { 0x0000, 0x0000, 0xFFFF, 0xFFFF }; 00761 ar_data ones64 = { 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF }; 00762 ar_data *ones; 00763 ar_data zeros = { 0x0000, 0x0000, 0x0000, 0x0000 }; 00764 00765 ar_data mask; 00766 ar_data rotatee; 00767 ar_data temp; 00768 00769 if (*resulttype != *opndtype || 00770 AR_CLASS (*resulttype) != AR_CLASS_INT || 00771 AR_CLASS (*shifttype) != AR_CLASS_INT || 00772 AR_CLASS (*sizetype) != AR_CLASS_INT || 00773 AR_INT_SIZE(*opndtype) == AR_INT_SIZE_24 || 00774 AR_INT_SIZE(*shifttype) == AR_INT_SIZE_24 || 00775 AR_INT_SIZE(*sizetype) == AR_INT_SIZE_24) 00776 return AR_STAT_INVALID_TYPE; 00777 00778 switch (AR_INT_SIZE (*opndtype)) { 00779 case AR_INT_SIZE_8: 00780 INT8_TO_HOST_SINT64(shift_count, shift); 00781 INT8_TO_HOST_SINT64(shift_size, size); 00782 type_size = 8; 00783 ones = &ones8; 00784 break; 00785 case AR_INT_SIZE_16: 00786 INT16_TO_HOST_SINT64(shift_count, shift); 00787 INT16_TO_HOST_SINT64(shift_size, size); 00788 type_size = 16; 00789 ones = &ones16; 00790 break; 00791 case AR_INT_SIZE_32: 00792 INT32_TO_HOST_SINT64(shift_count, shift); 00793 INT32_TO_HOST_SINT64(shift_size, size); 00794 type_size = 32; 00795 ones = &ones32; 00796 break; 00797 case AR_INT_SIZE_46: 00798 case AR_INT_SIZE_64: 00799 INT64_TO_HOST_SINT64(shift_count, shift); 00800 INT64_TO_HOST_SINT64(shift_size, size); 00801 type_size = 64; 00802 ones = &ones64; 00803 break; 00804 default: 00805 return (AR_STAT_INVALID_TYPE); 00806 } 00807 00808 /* 00809 * A right rotation of "shift" is the same as a 00810 * left one of "size" - "shift". 00811 */ 00812 if (shift_count < 0) 00813 shift_count = shift_size + shift_count; 00814 00815 /* 00816 * Shift_size has to be in [1, type_size], and 00817 * shift_count has to be in [0, shift_size]. 00818 */ 00819 if (shift_size < 1 || shift_size > type_size || 00820 shift_count < 0 || shift_count > shift_size) 00821 return AR_STAT_UNDEFINED; 00822 00823 /* 00824 * We now have shift_size in [1, type_size), and 00825 * shift_count in [1, shift_size). 00826 */ 00827 00828 /* 00829 * Extract just the unchanged part, and put it in the 00830 * result. Throw away any insignificant high bits 00831 * from the operand. 00832 */ 00833 ar_dblshift(&mask, resulttype, ones, &zeros, 00834 (type_size - (int) shift_size)); 00835 (void) AR_bitand((AR_DATA*) result, resulttype, 00836 (AR_DATA*) opnd, resulttype, 00837 (AR_DATA*) &mask, resulttype); 00838 (void) AR_bitand((AR_DATA*) result, resulttype, 00839 (AR_DATA*) result, resulttype, 00840 (AR_DATA*) ones, resulttype); 00841 00842 /* 00843 * Extract just the part that we'll rotate. 00844 */ 00845 ar_dblshift(&mask, resulttype, &zeros, ones, 00846 (type_size - (int) shift_size)); 00847 (void) AR_bitand((AR_DATA*) &rotatee, resulttype, 00848 (AR_DATA*) opnd, resulttype, 00849 (AR_DATA*) &mask, resulttype); 00850 00851 /* 00852 * Shift the right part of the rotated result 00853 * right into its correct position. This 00854 * leaves no extraneous bits, so we can then 00855 * OR it into the result. 00856 */ 00857 ar_dblshift(&temp, resulttype, &zeros, &rotatee, 00858 ((int) (shift_size - shift_count))); 00859 (void) AR_bitor((AR_DATA*) result, resulttype, 00860 (AR_DATA*) result, resulttype, 00861 (AR_DATA*) &temp, resulttype); 00862 00863 /* 00864 * Left-justify the left part of the rotated 00865 * result, removing the original bits to its 00866 * left. 00867 */ 00868 ar_dblshift(&temp, resulttype, &rotatee, &zeros, 00869 ((int) (shift_size - shift_count))); 00870 00871 /* 00872 * Shift the left part of the rotated result 00873 * result right into its correct position. This 00874 * leaves no extraneous bits, so we can then OR 00875 * it into the result. 00876 */ 00877 ar_dblshift(&temp, resulttype, &zeros, &temp, 00878 (type_size - (int) shift_size)); 00879 (void) AR_bitor((AR_DATA*) result, resulttype, 00880 (AR_DATA*) result, resulttype, 00881 (AR_DATA*) &temp, resulttype); 00882 00883 return AR_status ((AR_DATA*)result, resulttype); 00884 } 00885 00886 00887 00888 int 00889 AR_ibits (AR_DATA *res, const AR_TYPE *resulttype, 00890 const AR_DATA *opd, const AR_TYPE *opndtype, 00891 const AR_DATA *shft, const AR_TYPE *shifttype, 00892 const AR_DATA *sz, const AR_TYPE *sizetype) { 00893 ar_data *result = (ar_data*)res; 00894 ar_data *opnd = (ar_data*)opd; 00895 ar_data *shift = (ar_data*)shft; 00896 ar_data *size = (ar_data*)sz; 00897 00898 AR_HOST_SINT64 shift_count; 00899 AR_HOST_SINT64 shift_size; 00900 int type_size; 00901 00902 ar_data zeros = { 0x0000, 0x0000, 0x0000, 0x0000 }; 00903 00904 ar_data temp; 00905 00906 if (*resulttype != *opndtype || 00907 AR_CLASS (*resulttype) != AR_CLASS_INT || 00908 AR_CLASS (*shifttype) != AR_CLASS_INT || 00909 AR_CLASS (*sizetype) != AR_CLASS_INT || 00910 AR_INT_SIZE(*opndtype) == AR_INT_SIZE_24 || 00911 AR_INT_SIZE(*shifttype) == AR_INT_SIZE_24 || 00912 AR_INT_SIZE(*sizetype) == AR_INT_SIZE_24) 00913 return AR_STAT_INVALID_TYPE; 00914 00915 switch (AR_INT_SIZE (*opndtype)) { 00916 case AR_INT_SIZE_8: 00917 INT8_TO_HOST_SINT64(shift_count, shift); 00918 INT8_TO_HOST_SINT64(shift_size, size); 00919 type_size = 8; 00920 break; 00921 case AR_INT_SIZE_16: 00922 INT16_TO_HOST_SINT64(shift_count, shift); 00923 INT16_TO_HOST_SINT64(shift_size, size); 00924 type_size = 16; 00925 break; 00926 case AR_INT_SIZE_32: 00927 INT32_TO_HOST_SINT64(shift_count, shift); 00928 INT32_TO_HOST_SINT64(shift_size, size); 00929 type_size = 32; 00930 break; 00931 case AR_INT_SIZE_46: 00932 case AR_INT_SIZE_64: 00933 INT64_TO_HOST_SINT64(shift_count, shift); 00934 INT64_TO_HOST_SINT64(shift_size, size); 00935 type_size = 64; 00936 break; 00937 default: 00938 return (AR_STAT_INVALID_TYPE); 00939 } 00940 00941 /* 00942 * Shift_size has to be nonnegative, and shift_count 00943 * has to be in [0, (type_size - shift_size)]. 00944 */ 00945 if (shift_size < 0 || 00946 shift_count < 0 || shift_count > (type_size - shift_size)) 00947 return AR_STAT_UNDEFINED; 00948 00949 /* 00950 * Left shift the operand to throw away the bits above 00951 * the ones we want, then right shift it (zero-filling) 00952 * to right justify them. 00953 */ 00954 ar_dblshift(&temp, resulttype, opnd, &zeros, 00955 ((int) shift_count + (int) shift_size)); 00956 ar_dblshift(result, resulttype, &zeros, &temp, 00957 (type_size - (int) shift_size)); 00958 00959 return AR_status ((AR_DATA*)result, resulttype); 00960 } 00961 00962 00963 /* Mask creation. Count in [0, AR_INT_SIZE-1] creates a left mask; count 00964 * in [AR_INT_SIZE, 2*AR_INT_SIZE] makes a right-justified mask. 00965 */ 00966 int 00967 AR_mask (AR_DATA *res, const AR_TYPE *resulttype, 00968 const AR_DATA *cnt, const AR_TYPE *counttype) { 00969 ar_data* result = (ar_data*)res; 00970 ar_data* count = (ar_data*)cnt; 00971 00972 ar_data ones8 = { 0x0000, 0x0000, 0x0000, 0x00FF }; 00973 ar_data ones16 = { 0x0000, 0x0000, 0x0000, 0xFFFF }; 00974 ar_data ones32 = { 0x0000, 0x0000, 0xFFFF, 0xFFFF }; 00975 ar_data ones64 = { 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF }; 00976 ar_data zeros = { 0x0000, 0x0000, 0x0000, 0x0000 }; 00977 00978 if (*resulttype != *counttype || 00979 AR_CLASS (*resulttype) != AR_CLASS_INT || 00980 AR_CLASS (*counttype) != AR_CLASS_INT) 00981 return AR_STAT_INVALID_TYPE; 00982 00983 switch (AR_INT_SIZE (*resulttype)) { 00984 case AR_INT_SIZE_8: 00985 /* Check for shift count not in [0,16] */ 00986 if (count->ar_i8.part5 > 16) { 00987 ZERO_INT8(result); 00988 return AR_STAT_UNDEFINED; 00989 } 00990 00991 /* Use general circular shifter */ 00992 ar_dblshift (result, resulttype, 00993 &ones8, &zeros, count->ar_i8.part5); 00994 break; 00995 00996 case AR_INT_SIZE_16: 00997 /* Check for shift count not in [0,32] */ 00998 if (count->ar_i64.part4 > 32) { 00999 ZERO_INT16(result); 01000 return AR_STAT_UNDEFINED; 01001 } 01002 01003 /* Use general circular shifter */ 01004 ar_dblshift (result, resulttype, 01005 &ones16, &zeros, count->ar_i64.part4); 01006 break; 01007 01008 case AR_INT_SIZE_32: 01009 /* Check for shift count not in [0,64] */ 01010 if (count->ar_i64.part3 || count->ar_i64.part4 > 64) { 01011 ZERO_INT32(result); 01012 return AR_STAT_UNDEFINED; 01013 } 01014 01015 /* Use general circular shifter */ 01016 ar_dblshift (result, resulttype, 01017 &ones32, &zeros, count->ar_i64.part4); 01018 break; 01019 01020 case AR_INT_SIZE_46: 01021 case AR_INT_SIZE_64: 01022 /* Check for shift count not in [0,128] */ 01023 if (count->ar_i64.part1 | count->ar_i64.part2 | 01024 count->ar_i64.part3 || count->ar_i64.part4 > 128) { 01025 ZERO_INT64(result); 01026 return AR_STAT_UNDEFINED; 01027 } 01028 01029 /* Use general circular shifter */ 01030 ar_dblshift (result, resulttype, 01031 &ones64, &zeros, count->ar_i64.part4); 01032 break; 01033 01034 default: 01035 return (AR_STAT_INVALID_TYPE); 01036 } 01037 01038 return AR_status ((AR_DATA*)result, resulttype); 01039 } 01040 01041 01042 /* Leading zero count */ 01043 int 01044 AR_leadz (AR_DATA *res, const AR_TYPE *resulttype, 01045 const AR_DATA *opd, const AR_TYPE *opndtype) { 01046 ar_data* result = (ar_data*)res; 01047 ar_data* opnd = (ar_data*)opd; 01048 01049 int leadz, mask = 0x8000, mask8 = 0x80; 01050 01051 if (AR_CLASS (*resulttype) != AR_CLASS_INT || 01052 AR_INT_SIZE (*resulttype) != AR_INT_SIZE_8 && 01053 AR_INT_SIZE (*resulttype) != AR_INT_SIZE_16 && 01054 AR_INT_SIZE (*resulttype) != AR_INT_SIZE_32 && 01055 AR_INT_SIZE (*resulttype) != AR_INT_SIZE_46 && 01056 AR_INT_SIZE (*resulttype) != AR_INT_SIZE_64) 01057 return AR_STAT_INVALID_TYPE; 01058 01059 if (AR_CLASS (*opndtype) == AR_CLASS_INT && 01060 AR_INT_SIZE (*opndtype) == AR_INT_SIZE_8) { 01061 if (opnd->ar_i8.part5) 01062 for (leadz = 0; !(mask8 & opnd->ar_i8.part5); 01063 mask8 >>= 1) 01064 leadz++; 01065 else 01066 leadz = 8; 01067 } 01068 else if (AR_CLASS (*opndtype) == AR_CLASS_INT && 01069 AR_INT_SIZE (*opndtype) == AR_INT_SIZE_16) { 01070 if (opnd->ar_i64.part4) 01071 for (leadz = 0; !(mask & opnd->ar_i64.part4); 01072 mask >>= 1) 01073 leadz++; 01074 else 01075 leadz = 16; 01076 } 01077 else if ((AR_CLASS (*opndtype) == AR_CLASS_INT && 01078 AR_INT_SIZE (*opndtype) == AR_INT_SIZE_32) || 01079 (AR_CLASS (*opndtype) == AR_CLASS_FLOAT && 01080 AR_FLOAT_IS_COMPLEX (*opndtype) == AR_FLOAT_SIMPLE && 01081 AR_FLOAT_SIZE(*opndtype) == AR_FLOAT_32)) { 01082 if (opnd->ar_i64.part3) 01083 for (leadz = 0; !(mask & opnd->ar_i64.part3); 01084 mask >>= 1) 01085 leadz++; 01086 else if (opnd->ar_i64.part4) 01087 for (leadz = 16; !(mask & opnd->ar_i64.part4); 01088 mask >>= 1) 01089 leadz++; 01090 else 01091 leadz = 32; 01092 } 01093 else if ((AR_CLASS (*opndtype) == AR_CLASS_INT && 01094 (AR_INT_SIZE (*opndtype) == AR_INT_SIZE_46 || 01095 AR_INT_SIZE (*opndtype) == AR_INT_SIZE_64)) || 01096 (AR_CLASS (*opndtype) == AR_CLASS_FLOAT && 01097 AR_FLOAT_IS_COMPLEX (*opndtype) == AR_FLOAT_SIMPLE && 01098 AR_FLOAT_SIZE(*opndtype) == AR_FLOAT_64)) { 01099 if (opnd->ar_i64.part1) 01100 for (leadz = 0; !(mask & opnd->ar_i64.part1); 01101 mask >>= 1) 01102 leadz++; 01103 else if (opnd->ar_i64.part2) 01104 for (leadz = 16; !(mask & opnd->ar_i64.part2); 01105 mask >>= 1) 01106 leadz++; 01107 else if (opnd->ar_i64.part3) 01108 for (leadz = 32; !(mask & opnd->ar_i64.part3); 01109 mask >>= 1) 01110 leadz++; 01111 else if (opnd->ar_i64.part4) 01112 for (leadz = 48; !(mask & opnd->ar_i64.part4); 01113 mask >>= 1) 01114 leadz++; 01115 else 01116 leadz = 64; 01117 } 01118 else { 01119 return AR_STAT_INVALID_TYPE; 01120 } 01121 01122 ZERO_INT16_UPPER(result); 01123 result->ar_i64.part4 = leadz; 01124 01125 return AR_status ((AR_DATA*)result, resulttype); 01126 } 01127 01128 01129 /* Bit population count */ 01130 int 01131 AR_popcnt (AR_DATA *res, const AR_TYPE *resulttype, 01132 const AR_DATA *opd, const AR_TYPE *opndtype) { 01133 ar_data* result = (ar_data*)res; 01134 ar_data* opnd = (ar_data*)opd; 01135 01136 unsigned int i, popcnt = 0; 01137 01138 if (AR_CLASS (*resulttype) != AR_CLASS_INT || 01139 AR_INT_SIZE (*resulttype) != AR_INT_SIZE_8 && 01140 AR_INT_SIZE (*resulttype) != AR_INT_SIZE_16 && 01141 AR_INT_SIZE (*resulttype) != AR_INT_SIZE_32 && 01142 AR_INT_SIZE (*resulttype) != AR_INT_SIZE_46 && 01143 AR_INT_SIZE (*resulttype) != AR_INT_SIZE_64) 01144 return AR_STAT_INVALID_TYPE; 01145 01146 if (AR_CLASS (*opndtype) == AR_CLASS_INT) { 01147 switch (AR_INT_SIZE (*opndtype)) { 01148 case AR_INT_SIZE_8: 01149 for (i = opnd->ar_i8.part5; i; i >>= 1) 01150 popcnt += i & 1; 01151 break; 01152 01153 case AR_INT_SIZE_16: 01154 for (i = opnd->ar_i64.part4; i; i >>= 1) 01155 popcnt += i & 1; 01156 break; 01157 01158 case AR_INT_SIZE_32: 01159 for (i = opnd->ar_i64.part3; i; i >>= 1) 01160 popcnt += i & 1; 01161 for (i = opnd->ar_i64.part4; i; i >>= 1) 01162 popcnt += i & 1; 01163 break; 01164 01165 case AR_INT_SIZE_46: 01166 case AR_INT_SIZE_64: 01167 for (i = opnd->ar_i64.part1; i; i >>= 1) 01168 popcnt += i & 1; 01169 for (i = opnd->ar_i64.part2; i; i >>= 1) 01170 popcnt += i & 1; 01171 for (i = opnd->ar_i64.part3; i; i >>= 1) 01172 popcnt += i & 1; 01173 for (i = opnd->ar_i64.part4; i; i >>= 1) 01174 popcnt += i & 1; 01175 break; 01176 01177 default: 01178 return AR_STAT_INVALID_TYPE; 01179 } 01180 } 01181 else if (AR_CLASS (*opndtype) == AR_CLASS_FLOAT && 01182 AR_FLOAT_IS_COMPLEX (*opndtype) == AR_FLOAT_SIMPLE) { 01183 for (i = opnd->ar_i64.part3; i; i >>= 1) 01184 popcnt += i & 1; 01185 for (i = opnd->ar_i64.part4; i; i >>= 1) 01186 popcnt += i & 1; 01187 if (AR_FLOAT_SIZE(*opndtype) == AR_FLOAT_64) { 01188 for (i = opnd->ar_i64.part1; i; i >>= 1) 01189 popcnt += i & 1; 01190 for (i = opnd->ar_i64.part2; i; i >>= 1) 01191 popcnt += i & 1; 01192 } 01193 else if (AR_FLOAT_SIZE(*opndtype) != AR_FLOAT_32) { 01194 return AR_STAT_INVALID_TYPE; 01195 } 01196 } 01197 else { 01198 return AR_STAT_INVALID_TYPE; 01199 } 01200 01201 result->ar_i64.part1 = result->ar_i64.part2 = result->ar_i64.part3 = 0; 01202 result->ar_i64.part4 = popcnt; 01203 01204 return AR_status ((AR_DATA*)result, resulttype); 01205 } 01206 01207 01208 /* Bit population count parity (0 if pop count even, 1 if odd) */ 01209 int 01210 AR_poppar (AR_DATA *res, const AR_TYPE *resulttype, 01211 const AR_DATA *opd, const AR_TYPE *opndtype) { 01212 ar_data* result = (ar_data*)res; 01213 ar_data* opnd = (ar_data*)opd; 01214 01215 unsigned int poppar = 0; 01216 01217 if (AR_CLASS (*resulttype) != AR_CLASS_INT || 01218 AR_INT_SIZE (*resulttype) != AR_INT_SIZE_8 && 01219 AR_INT_SIZE (*resulttype) != AR_INT_SIZE_16 && 01220 AR_INT_SIZE (*resulttype) != AR_INT_SIZE_32 && 01221 AR_INT_SIZE (*resulttype) != AR_INT_SIZE_46 && 01222 AR_INT_SIZE (*resulttype) != AR_INT_SIZE_64) 01223 return AR_STAT_INVALID_TYPE; 01224 01225 if (AR_CLASS (*opndtype) == AR_CLASS_INT) { 01226 switch (AR_INT_SIZE (*opndtype)) { 01227 case AR_INT_SIZE_8: 01228 poppar ^= opnd->ar_i8.part5; 01229 break; 01230 01231 case AR_INT_SIZE_16: 01232 poppar ^= opnd->ar_i64.part4; 01233 break; 01234 01235 case AR_INT_SIZE_32: 01236 poppar ^= opnd->ar_i64.part3 ^ 01237 opnd->ar_i64.part4; 01238 break; 01239 01240 case AR_INT_SIZE_46: 01241 case AR_INT_SIZE_64: 01242 poppar ^= opnd->ar_i64.part1 ^ 01243 opnd->ar_i64.part2 ^ 01244 opnd->ar_i64.part3 ^ 01245 opnd->ar_i64.part4; 01246 break; 01247 01248 default: 01249 return AR_STAT_INVALID_TYPE; 01250 } 01251 } 01252 else if (AR_CLASS (*opndtype) == AR_CLASS_FLOAT && 01253 AR_FLOAT_IS_COMPLEX (*opndtype) == AR_FLOAT_SIMPLE) { 01254 poppar = opnd->ar_i64.part3 ^ opnd->ar_i64.part4; 01255 if (AR_FLOAT_SIZE(*opndtype) == AR_FLOAT_64) { 01256 poppar ^= opnd->ar_i64.part1 ^ opnd->ar_i64.part2; 01257 } 01258 else if (AR_FLOAT_SIZE(*opndtype) != AR_FLOAT_32) { 01259 return AR_STAT_INVALID_TYPE; 01260 } 01261 } 01262 else { 01263 return AR_STAT_INVALID_TYPE; 01264 } 01265 01266 poppar = (poppar & 0xFF) ^ (poppar >> 8); 01267 poppar = (poppar & 0x0F) ^ (poppar >> 4); 01268 poppar = (poppar & 0x03) ^ (poppar >> 2); 01269 poppar = (poppar & 0x01) ^ (poppar >> 1); 01270 01271 ZERO_INT16_UPPER(result); 01272 result->ar_i64.part4 = poppar; 01273 01274 return AR_status ((AR_DATA*)result, resulttype); 01275 } 01276 01277 static char USMID [] = "\n%Z%%M% %I% %G% %U%\n"; 01278 static char rcsid [] = "$Id: bits.c,v 1.1.1.1 2002-05-22 20:06:18 dsystem Exp $";