0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023 #include <asm/div64.h>
0024
0025 #define SHIFT_AMOUNT 16
0026
0027 #define PRECISION 5
0028
0029 #define SHIFTED_2 (2 << SHIFT_AMOUNT)
0030 #define MAX (1 << (SHIFT_AMOUNT - 1)) - 1
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041 typedef union _fInt {
0042 int full;
0043 struct _partial {
0044 unsigned int decimal: SHIFT_AMOUNT;
0045 int real: 32 - SHIFT_AMOUNT;
0046 } partial;
0047 } fInt;
0048
0049
0050
0051
0052
0053 static fInt ConvertToFraction(int);
0054 static fInt Convert_ULONG_ToFraction(uint32_t);
0055 static fInt GetScaledFraction(int, int);
0056 static int ConvertBackToInteger(fInt);
0057
0058 static fInt fNegate(fInt);
0059 static fInt fAdd (fInt, fInt);
0060 static fInt fSubtract (fInt A, fInt B);
0061 static fInt fMultiply (fInt, fInt);
0062 static fInt fDivide (fInt A, fInt B);
0063 static fInt fGetSquare(fInt);
0064 static fInt fSqrt(fInt);
0065
0066 static int uAbs(int);
0067 static int uPow(int base, int exponent);
0068
0069 static void SolveQuadracticEqn(fInt, fInt, fInt, fInt[]);
0070 static bool Equal(fInt, fInt);
0071 static bool GreaterThan(fInt A, fInt B);
0072
0073 static fInt fExponential(fInt exponent);
0074 static fInt fNaturalLog(fInt value);
0075
0076
0077
0078
0079 static fInt fDecodeLinearFuse(uint32_t fuse_value, fInt f_min, fInt f_range, uint32_t bitlength);
0080 static fInt fDecodeLogisticFuse(uint32_t fuse_value, fInt f_average, fInt f_range, uint32_t bitlength);
0081 static fInt fDecodeLeakageID (uint32_t leakageID_fuse, fInt ln_max_div_min, fInt f_min, uint32_t bitlength);
0082
0083
0084
0085
0086
0087 static fInt Divide (int, int);
0088 static fInt fNegate(fInt);
0089
0090 static int uGetScaledDecimal (fInt);
0091 static int GetReal (fInt A);
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108 static fInt fExponential(fInt exponent)
0109 {
0110 uint32_t i;
0111 bool bNegated = false;
0112
0113 fInt fPositiveOne = ConvertToFraction(1);
0114 fInt fZERO = ConvertToFraction(0);
0115
0116 fInt lower_bound = Divide(78, 10000);
0117 fInt solution = fPositiveOne;
0118 fInt error_term;
0119
0120 static const uint32_t k_array[11] = {55452, 27726, 13863, 6931, 4055, 2231, 1178, 606, 308, 155, 78};
0121 static const uint32_t expk_array[11] = {2560000, 160000, 40000, 20000, 15000, 12500, 11250, 10625, 10313, 10156, 10078};
0122
0123 if (GreaterThan(fZERO, exponent)) {
0124 exponent = fNegate(exponent);
0125 bNegated = true;
0126 }
0127
0128 while (GreaterThan(exponent, lower_bound)) {
0129 for (i = 0; i < 11; i++) {
0130 if (GreaterThan(exponent, GetScaledFraction(k_array[i], 10000))) {
0131 exponent = fSubtract(exponent, GetScaledFraction(k_array[i], 10000));
0132 solution = fMultiply(solution, GetScaledFraction(expk_array[i], 10000));
0133 }
0134 }
0135 }
0136
0137 error_term = fAdd(fPositiveOne, exponent);
0138
0139 solution = fMultiply(solution, error_term);
0140
0141 if (bNegated)
0142 solution = fDivide(fPositiveOne, solution);
0143
0144 return solution;
0145 }
0146
0147 static fInt fNaturalLog(fInt value)
0148 {
0149 uint32_t i;
0150 fInt upper_bound = Divide(8, 1000);
0151 fInt fNegativeOne = ConvertToFraction(-1);
0152 fInt solution = ConvertToFraction(0);
0153 fInt error_term;
0154
0155 static const uint32_t k_array[10] = {160000, 40000, 20000, 15000, 12500, 11250, 10625, 10313, 10156, 10078};
0156 static const uint32_t logk_array[10] = {27726, 13863, 6931, 4055, 2231, 1178, 606, 308, 155, 78};
0157
0158 while (GreaterThan(fAdd(value, fNegativeOne), upper_bound)) {
0159 for (i = 0; i < 10; i++) {
0160 if (GreaterThan(value, GetScaledFraction(k_array[i], 10000))) {
0161 value = fDivide(value, GetScaledFraction(k_array[i], 10000));
0162 solution = fAdd(solution, GetScaledFraction(logk_array[i], 10000));
0163 }
0164 }
0165 }
0166
0167 error_term = fAdd(fNegativeOne, value);
0168
0169 return (fAdd(solution, error_term));
0170 }
0171
0172 static fInt fDecodeLinearFuse(uint32_t fuse_value, fInt f_min, fInt f_range, uint32_t bitlength)
0173 {
0174 fInt f_fuse_value = Convert_ULONG_ToFraction(fuse_value);
0175 fInt f_bit_max_value = Convert_ULONG_ToFraction((uPow(2, bitlength)) - 1);
0176
0177 fInt f_decoded_value;
0178
0179 f_decoded_value = fDivide(f_fuse_value, f_bit_max_value);
0180 f_decoded_value = fMultiply(f_decoded_value, f_range);
0181 f_decoded_value = fAdd(f_decoded_value, f_min);
0182
0183 return f_decoded_value;
0184 }
0185
0186
0187 static fInt fDecodeLogisticFuse(uint32_t fuse_value, fInt f_average, fInt f_range, uint32_t bitlength)
0188 {
0189 fInt f_fuse_value = Convert_ULONG_ToFraction(fuse_value);
0190 fInt f_bit_max_value = Convert_ULONG_ToFraction((uPow(2, bitlength)) - 1);
0191
0192 fInt f_CONSTANT_NEG13 = ConvertToFraction(-13);
0193 fInt f_CONSTANT1 = ConvertToFraction(1);
0194
0195 fInt f_decoded_value;
0196
0197 f_decoded_value = fSubtract(fDivide(f_bit_max_value, f_fuse_value), f_CONSTANT1);
0198 f_decoded_value = fNaturalLog(f_decoded_value);
0199 f_decoded_value = fMultiply(f_decoded_value, fDivide(f_range, f_CONSTANT_NEG13));
0200 f_decoded_value = fAdd(f_decoded_value, f_average);
0201
0202 return f_decoded_value;
0203 }
0204
0205 static fInt fDecodeLeakageID (uint32_t leakageID_fuse, fInt ln_max_div_min, fInt f_min, uint32_t bitlength)
0206 {
0207 fInt fLeakage;
0208 fInt f_bit_max_value = Convert_ULONG_ToFraction((uPow(2, bitlength)) - 1);
0209
0210 fLeakage = fMultiply(ln_max_div_min, Convert_ULONG_ToFraction(leakageID_fuse));
0211 fLeakage = fDivide(fLeakage, f_bit_max_value);
0212 fLeakage = fExponential(fLeakage);
0213 fLeakage = fMultiply(fLeakage, f_min);
0214
0215 return fLeakage;
0216 }
0217
0218 static fInt ConvertToFraction(int X)
0219 {
0220 fInt temp;
0221
0222 if (X <= MAX)
0223 temp.full = (X << SHIFT_AMOUNT);
0224 else
0225 temp.full = 0;
0226
0227 return temp;
0228 }
0229
0230 static fInt fNegate(fInt X)
0231 {
0232 fInt CONSTANT_NEGONE = ConvertToFraction(-1);
0233 return (fMultiply(X, CONSTANT_NEGONE));
0234 }
0235
0236 static fInt Convert_ULONG_ToFraction(uint32_t X)
0237 {
0238 fInt temp;
0239
0240 if (X <= MAX)
0241 temp.full = (X << SHIFT_AMOUNT);
0242 else
0243 temp.full = 0;
0244
0245 return temp;
0246 }
0247
0248 static fInt GetScaledFraction(int X, int factor)
0249 {
0250 int times_shifted, factor_shifted;
0251 bool bNEGATED;
0252 fInt fValue;
0253
0254 times_shifted = 0;
0255 factor_shifted = 0;
0256 bNEGATED = false;
0257
0258 if (X < 0) {
0259 X = -1*X;
0260 bNEGATED = true;
0261 }
0262
0263 if (factor < 0) {
0264 factor = -1*factor;
0265 bNEGATED = !bNEGATED;
0266 }
0267
0268 if ((X > MAX) || factor > MAX) {
0269 if ((X/factor) <= MAX) {
0270 while (X > MAX) {
0271 X = X >> 1;
0272 times_shifted++;
0273 }
0274
0275 while (factor > MAX) {
0276 factor = factor >> 1;
0277 factor_shifted++;
0278 }
0279 } else {
0280 fValue.full = 0;
0281 return fValue;
0282 }
0283 }
0284
0285 if (factor == 1)
0286 return ConvertToFraction(X);
0287
0288 fValue = fDivide(ConvertToFraction(X * uPow(-1, bNEGATED)), ConvertToFraction(factor));
0289
0290 fValue.full = fValue.full << times_shifted;
0291 fValue.full = fValue.full >> factor_shifted;
0292
0293 return fValue;
0294 }
0295
0296
0297 static fInt fAdd (fInt X, fInt Y)
0298 {
0299 fInt Sum;
0300
0301 Sum.full = X.full + Y.full;
0302
0303 return Sum;
0304 }
0305
0306
0307 static fInt fSubtract (fInt X, fInt Y)
0308 {
0309 fInt Difference;
0310
0311 Difference.full = X.full - Y.full;
0312
0313 return Difference;
0314 }
0315
0316 static bool Equal(fInt A, fInt B)
0317 {
0318 if (A.full == B.full)
0319 return true;
0320 else
0321 return false;
0322 }
0323
0324 static bool GreaterThan(fInt A, fInt B)
0325 {
0326 if (A.full > B.full)
0327 return true;
0328 else
0329 return false;
0330 }
0331
0332 static fInt fMultiply (fInt X, fInt Y)
0333 {
0334 fInt Product;
0335 int64_t tempProduct;
0336
0337
0338
0339
0340
0341
0342
0343
0344
0345
0346
0347
0348
0349 tempProduct = ((int64_t)X.full) * ((int64_t)Y.full);
0350 tempProduct = tempProduct >> 16;
0351 Product.full = (int)tempProduct;
0352
0353 return Product;
0354 }
0355
0356 static fInt fDivide (fInt X, fInt Y)
0357 {
0358 fInt fZERO, fQuotient;
0359 int64_t longlongX, longlongY;
0360
0361 fZERO = ConvertToFraction(0);
0362
0363 if (Equal(Y, fZERO))
0364 return fZERO;
0365
0366 longlongX = (int64_t)X.full;
0367 longlongY = (int64_t)Y.full;
0368
0369 longlongX = longlongX << 16;
0370
0371 div64_s64(longlongX, longlongY);
0372
0373 fQuotient.full = (int)longlongX;
0374 return fQuotient;
0375 }
0376
0377 static int ConvertBackToInteger (fInt A)
0378 {
0379 fInt fullNumber, scaledDecimal, scaledReal;
0380
0381 scaledReal.full = GetReal(A) * uPow(10, PRECISION-1);
0382
0383 scaledDecimal.full = uGetScaledDecimal(A);
0384
0385 fullNumber = fAdd(scaledDecimal,scaledReal);
0386
0387 return fullNumber.full;
0388 }
0389
0390 static fInt fGetSquare(fInt A)
0391 {
0392 return fMultiply(A,A);
0393 }
0394
0395
0396 static fInt fSqrt(fInt num)
0397 {
0398 fInt F_divide_Fprime, Fprime;
0399 fInt test;
0400 fInt twoShifted;
0401 int seed, counter, error;
0402 fInt x_new, x_old, C, y;
0403
0404 fInt fZERO = ConvertToFraction(0);
0405
0406
0407
0408 if (GreaterThan(fZERO, num) || Equal(fZERO, num))
0409 return fZERO;
0410
0411 C = num;
0412
0413 if (num.partial.real > 3000)
0414 seed = 60;
0415 else if (num.partial.real > 1000)
0416 seed = 30;
0417 else if (num.partial.real > 100)
0418 seed = 10;
0419 else
0420 seed = 2;
0421
0422 counter = 0;
0423
0424 if (Equal(num, fZERO))
0425 return fZERO;
0426
0427 twoShifted = ConvertToFraction(2);
0428 x_new = ConvertToFraction(seed);
0429
0430 do {
0431 counter++;
0432
0433 x_old.full = x_new.full;
0434
0435 test = fGetSquare(x_old);
0436 y = fSubtract(test, C);
0437
0438 Fprime = fMultiply(twoShifted, x_old);
0439 F_divide_Fprime = fDivide(y, Fprime);
0440
0441 x_new = fSubtract(x_old, F_divide_Fprime);
0442
0443 error = ConvertBackToInteger(x_new) - ConvertBackToInteger(x_old);
0444
0445 if (counter > 20)
0446 return x_new;
0447
0448 } while (uAbs(error) > 0);
0449
0450 return (x_new);
0451 }
0452
0453 static void SolveQuadracticEqn(fInt A, fInt B, fInt C, fInt Roots[])
0454 {
0455 fInt *pRoots = &Roots[0];
0456 fInt temp, root_first, root_second;
0457 fInt f_CONSTANT10, f_CONSTANT100;
0458
0459 f_CONSTANT100 = ConvertToFraction(100);
0460 f_CONSTANT10 = ConvertToFraction(10);
0461
0462 while(GreaterThan(A, f_CONSTANT100) || GreaterThan(B, f_CONSTANT100) || GreaterThan(C, f_CONSTANT100)) {
0463 A = fDivide(A, f_CONSTANT10);
0464 B = fDivide(B, f_CONSTANT10);
0465 C = fDivide(C, f_CONSTANT10);
0466 }
0467
0468 temp = fMultiply(ConvertToFraction(4), A);
0469 temp = fMultiply(temp, C);
0470 temp = fSubtract(fGetSquare(B), temp);
0471 temp = fSqrt(temp);
0472
0473 root_first = fSubtract(fNegate(B), temp);
0474 root_second = fAdd(fNegate(B), temp);
0475
0476 root_first = fDivide(root_first, ConvertToFraction(2));
0477 root_first = fDivide(root_first, A);
0478
0479 root_second = fDivide(root_second, ConvertToFraction(2));
0480 root_second = fDivide(root_second, A);
0481
0482 *(pRoots + 0) = root_first;
0483 *(pRoots + 1) = root_second;
0484 }
0485
0486
0487
0488
0489
0490
0491
0492 static int GetReal (fInt A)
0493 {
0494 return (A.full >> SHIFT_AMOUNT);
0495 }
0496
0497 static fInt Divide (int X, int Y)
0498 {
0499 fInt A, B, Quotient;
0500
0501 A.full = X << SHIFT_AMOUNT;
0502 B.full = Y << SHIFT_AMOUNT;
0503
0504 Quotient = fDivide(A, B);
0505
0506 return Quotient;
0507 }
0508
0509 static int uGetScaledDecimal (fInt A)
0510 {
0511 int dec[PRECISION];
0512 int i, scaledDecimal = 0, tmp = A.partial.decimal;
0513
0514 for (i = 0; i < PRECISION; i++) {
0515 dec[i] = tmp / (1 << SHIFT_AMOUNT);
0516 tmp = tmp - ((1 << SHIFT_AMOUNT)*dec[i]);
0517 tmp *= 10;
0518 scaledDecimal = scaledDecimal + dec[i]*uPow(10, PRECISION - 1 -i);
0519 }
0520
0521 return scaledDecimal;
0522 }
0523
0524 static int uPow(int base, int power)
0525 {
0526 if (power == 0)
0527 return 1;
0528 else
0529 return (base)*uPow(base, power - 1);
0530 }
0531
0532 static int uAbs(int X)
0533 {
0534 if (X < 0)
0535 return (X * -1);
0536 else
0537 return X;
0538 }
0539
0540 static fInt fRoundUpByStepSize(fInt A, fInt fStepSize, bool error_term)
0541 {
0542 fInt solution;
0543
0544 solution = fDivide(A, fStepSize);
0545 solution.partial.decimal = 0;
0546
0547 if (error_term)
0548 solution.partial.real += 1;
0549
0550 solution = fMultiply(solution, fStepSize);
0551 solution = fAdd(solution, fStepSize);
0552
0553 return solution;
0554 }
0555