Open64 (mfef90, whirl2f, and IR tools)  TAG: version-openad; SVN changeset: 916
bits.c
Go to the documentation of this file.
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 $";
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines