bignumber.c 45.3 KB
Newer Older
饶先宏's avatar
饶先宏 已提交
1
/*
饶先宏's avatar
饶先宏 已提交
2
** HDL4SE: 软件Verilog综合仿真平台
饶先宏's avatar
饶先宏 已提交
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
** Copyright (C) 2021-2021, raoxianhong<raoxianhong@163.net>
** LCOM: 轻量级组件对象模型
** Copyright (C) 2021-2021, raoxianhong<raoxianhong@163.net>
** All rights reserved.
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are met:
**
** * Redistributions of source code must retain the above copyright notice,
**   this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright notice,
**   this list of conditions and the following disclaimer in the documentation
**   and/or other materials provided with the distribution.
** * The name of the author may be used to endorse or promote products
**   derived from this software without specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
** THE POSSIBILITY OF SUCH DAMAGE.
*/

/*
* bignumber.c
    202105201110: rxh, initial version
饶先宏's avatar
饶先宏 已提交
35
	202105260952: rxh, 修改了接口,为verilog语言编译做准备,主要是区分了带符号和不带符号计算
饶先宏's avatar
饶先宏 已提交
36
	202106130718: rxh, 增加实现了DList接口,支持放在双向链表中
饶先宏's avatar
饶先宏 已提交
37
	202106190808: rxh, 在数字中增加是否带符号标记
38
	202106251628: rxh, 处理输入和输出宽度不确定的情况
饶先宏's avatar
饶先宏 已提交
39 40 41 42 43
*/

#include "stdlib.h" 
#include "stdio.h"
#include "object.h"
饶先宏's avatar
饶先宏 已提交
44
#include "dlist.h"
饶先宏's avatar
饶先宏 已提交
45
#include "string.h"
饶先宏's avatar
饶先宏 已提交
46 47
#define IMPLEMENT_GUID
#include "bignumber.h"
饶先宏's avatar
饶先宏 已提交
48 49
#undef IMPLEMENT_GUID

50 51
#define NOTIMPL printf("bignumber.c %d, %s is not implemented now\n", __LINE__, __FUNCTION__)

饶先宏's avatar
饶先宏 已提交
52 53 54
#define HDL4SEDEBUG 1

#if HDL4SEDEBUG
饶先宏's avatar
饶先宏 已提交
55
static char __debug_buf[60];
饶先宏's avatar
饶先宏 已提交
56
#endif
57

饶先宏's avatar
饶先宏 已提交
58
#define CELL_WIDTH 32
饶先宏's avatar
饶先宏 已提交
59
#define CELL_MASK 0xffffffff
饶先宏's avatar
饶先宏 已提交
60 61 62 63 64

typedef struct _sBigInteger {
	OBJECT_HEADER
	INTERFACE_DECLARE(IBigNumber)
	BIGNUMBER_VARDECLARE
饶先宏's avatar
饶先宏 已提交
65
	DLIST_VARDECLARE
饶先宏's avatar
饶先宏 已提交
66 67

	int buflen;
饶先宏's avatar
饶先宏 已提交
68
	int width;
饶先宏's avatar
饶先宏 已提交
69
	int isunsigned;
饶先宏's avatar
饶先宏 已提交
70 71 72
	unsigned int* buf;

}sBigInteger;
73
 
饶先宏's avatar
饶先宏 已提交
74 75
OBJECT_FUNCDECLARE(bigint, CLSID_BIGINTEGER);
BIGNUMBER_FUNCDECLARE(bigint, CLSID_BIGINTEGER, sBigInteger);
饶先宏's avatar
饶先宏 已提交
76 77
DLIST_FUNCIMPL(bigint, CLSID_BIGINTEGER, sBigInteger);

饶先宏's avatar
饶先宏 已提交
78 79 80 81 82

OBJECT_FUNCIMPL(bigint, sBigInteger, CLSID_BIGINTEGER);

QUERYINTERFACE_BEGIN(bigint, CLSID_BIGINTEGER)
QUERYINTERFACE_ITEM(IID_BIGNUMBER, IBigNumber, sBigInteger)
饶先宏's avatar
饶先宏 已提交
83
QUERYINTERFACE_ITEM(IID_DLIST, IDList, sBigInteger)
饶先宏's avatar
饶先宏 已提交
84 85 86 87
QUERYINTERFACE_END

static const char* bigintModuleInfo()
{
88
	return "1.0.1-20210625.1628 Big integer library";
饶先宏's avatar
饶先宏 已提交
89 90 91 92 93
}

static int bigintCreate(const PARAMITEM* pParams, int paramcount, HOBJECT* pObject)
{
	sBigInteger* pobj;
饶先宏's avatar
饶先宏 已提交
94
	int i;
饶先宏's avatar
饶先宏 已提交
95 96 97 98 99 100
	pobj = (sBigInteger*)malloc(sizeof(sBigInteger));
	if (pobj == NULL)
		return -1;
	*pObject = 0;
	BIGNUMBER_VARINIT(pobj, CLSID_BIGINTEGER);
	INTERFACE_INIT(IBigNumber, pobj, bigint, bn);
饶先宏's avatar
饶先宏 已提交
101
	DLIST_VARINIT(pobj, bigint);
饶先宏's avatar
饶先宏 已提交
102

饶先宏's avatar
饶先宏 已提交
103 104 105 106 107 108
	pobj->width = 64;
	for (i = 0; i < paramcount; i++) {
		if (pParams[i].name == PARAMID_BIGINTEGERWIDTH)
			pobj->width = pParams[i].i32value;
	}

109
	if (pobj->width <= 0)
110
		pobj->width = 64;
111

饶先宏's avatar
饶先宏 已提交
112
	pobj->isunsigned = -1;
饶先宏's avatar
饶先宏 已提交
113 114 115
	pobj->buflen = (pobj->width + CELL_WIDTH - 1) / CELL_WIDTH;
	if (pobj->buflen < 2)
		pobj->buflen = 2;
饶先宏's avatar
饶先宏 已提交
116
	pobj->buf = malloc(pobj->buflen * sizeof(unsigned int));
饶先宏's avatar
饶先宏 已提交
117 118 119 120 121
	if (pobj->buf == NULL)
		return -1;

	for (i = 0;i<pobj->buflen;i++)
		pobj->buf[i] = 0;
饶先宏's avatar
饶先宏 已提交
122 123 124 125 126 127 128 129 130 131

	/* 返回生成的对象 */
	OBJECT_RETURN_GEN(bigint, pobj, pObject, CLSID_BIGINTEGER);
	return EIID_OK;
}

static int actualwidth(unsigned int n)
{
	unsigned int c = 1;
	int ret = 1;
饶先宏's avatar
饶先宏 已提交
132
	if (n & 0x80000000)
饶先宏's avatar
饶先宏 已提交
133
		return CELL_WIDTH;
饶先宏's avatar
饶先宏 已提交
134
	while (c <= n) {
饶先宏's avatar
饶先宏 已提交
135 136 137
		c <<= 1;
		ret++;
	}
饶先宏's avatar
饶先宏 已提交
138
	return ret-1;
饶先宏's avatar
饶先宏 已提交
139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156
}

static void bigintDestroy(HOBJECT object)
{
	sBigInteger* pobj;
	pobj = (sBigInteger*)objectThis(object);
	free(pobj->buf);
	free(pobj);
}

static int bigintValid(HOBJECT object)
{
	sBigInteger* pobj;
	pobj = (sBigInteger*)objectThis(object);
	if (pobj == NULL)
		return 0;
	if (pobj->buflen < 2)
		return 0;
饶先宏's avatar
饶先宏 已提交
157 158
	if (pobj->buflen * CELL_WIDTH < pobj->width)
		return 0;
饶先宏's avatar
饶先宏 已提交
159 160 161 162 163
	if (pobj->buf == NULL)
		return 0;
	return 1;
}

饶先宏's avatar
饶先宏 已提交
164
static int bigint_bn_GetWidth(HOBJECT object)
饶先宏's avatar
饶先宏 已提交
165 166 167
{
	sBigInteger* pobj;
	pobj = (sBigInteger*)objectThis(object);
饶先宏's avatar
饶先宏 已提交
168
	return pobj->width;
饶先宏's avatar
饶先宏 已提交
169 170
}

饶先宏's avatar
饶先宏 已提交
171
static int bigint_bn_SetWidth(HOBJECT object, int width)
饶先宏's avatar
饶先宏 已提交
172
{
173
	int i, bc, blen, sign;
饶先宏's avatar
饶先宏 已提交
174 175
	sBigInteger* pobj;
	pobj = (sBigInteger*)objectThis(object);
饶先宏's avatar
饶先宏 已提交
176
	if (width <= 0) {
177
		return -1;
饶先宏's avatar
饶先宏 已提交
178
	}
饶先宏's avatar
饶先宏 已提交
179
	sign = 0;
饶先宏's avatar
饶先宏 已提交
180
	if (pobj->isunsigned == 0) {
饶先宏's avatar
饶先宏 已提交
181 182
		bc = (pobj->width - 1) / CELL_WIDTH;
		sign = pobj->buf[bc] & (1 << ((pobj->width-1) % (CELL_WIDTH-1)));
饶先宏's avatar
饶先宏 已提交
183 184 185
	}

	blen = (width + CELL_WIDTH - 1) / CELL_WIDTH;
186 187
	if (blen < 2)
		blen = 2;
饶先宏's avatar
饶先宏 已提交
188 189 190
	if (pobj->buflen < blen) {
		unsigned int * buf;
		buf = (unsigned int *)malloc(blen * (CELL_WIDTH / 8));
饶先宏's avatar
饶先宏 已提交
191 192 193 194 195 196 197 198
		if (buf == NULL)
			return -1;
		for (i = 0; i < pobj->buflen; i++)
			buf[i] = pobj->buf[i];
		pobj->buflen = blen;
		free(pobj->buf);
		pobj->buf = buf;
	}
饶先宏's avatar
饶先宏 已提交
199 200 201 202 203 204 205 206 207 208 209 210 211 212

	blen = pobj->width / CELL_WIDTH;
	if (blen < pobj->buflen) {
		bc = pobj->width & (CELL_WIDTH - 1);
		if (sign)
			pobj->buf[blen] |= CELL_MASK << bc;
		else
			pobj->buf[blen] &= CELL_MASK >> (CELL_WIDTH - bc);
	}
	for (i = blen + 1; i < pobj->buflen; i++) {
		pobj->buf[i] = sign ? CELL_MASK : 0;
	}


饶先宏's avatar
饶先宏 已提交
213 214 215 216 217 218 219 220
	blen = width / CELL_WIDTH;
	if (blen < pobj->buflen) {
		bc = width & (CELL_WIDTH - 1);
		if (sign)
			pobj->buf[blen] |= CELL_MASK << bc;
		else
			pobj->buf[blen] &= CELL_MASK >> (CELL_WIDTH - bc);
	}
饶先宏's avatar
饶先宏 已提交
221 222
	for (i = blen+1; i < pobj->buflen; i++) {
		pobj->buf[i] = sign ? CELL_MASK : 0;
饶先宏's avatar
饶先宏 已提交
223
	}
饶先宏's avatar
饶先宏 已提交
224
	pobj->width = width;
饶先宏's avatar
饶先宏 已提交
225 226 227
	return 0;
}

饶先宏's avatar
饶先宏 已提交
228 229 230 231 232 233 234 235 236 237 238
static int bigint_bn_IsUnsigned(HOBJECT object)
{
	sBigInteger* pobj;
	pobj = (sBigInteger*)objectThis(object);
	return pobj->isunsigned;
}

static int bigint_bn_SetUnsigned(HOBJECT object, int isunsigned)
{
	sBigInteger* pobj;
	pobj = (sBigInteger*)objectThis(object);
239
	pobj->isunsigned = isunsigned?1:0;
饶先宏's avatar
饶先宏 已提交
240 241 242 243 244
	bigint_bn_SetWidth(object, pobj->width);
	return 0;
}


245 246 247 248 249 250 251 252 253 254 255 256 257
static int bigint_bn_GetBits32(HOBJECT object, int ind32, unsigned int* pbits)
{
	sBigInteger* pobj;
	pobj = (sBigInteger*)objectThis(object); 
	if (ind32 < 0 || ind32 >= pobj->buflen) {
		*pbits = 0;
		return -1;
	}
	*pbits = pobj->buf[ind32];
	return 0;
}

static int bigint_bn_SetBits32(HOBJECT object, int ind32, unsigned int bits)
饶先宏's avatar
饶先宏 已提交
258 259 260
{
	sBigInteger* pobj;
	pobj = (sBigInteger*)objectThis(object);
261
	if (ind32 < 0 || ind32 >= pobj->buflen)
饶先宏's avatar
饶先宏 已提交
262
		return -1;
263
	pobj->buf[ind32] = bits;
饶先宏's avatar
饶先宏 已提交
264 265 266
	return 0;
}

267 268 269 270 271 272 273 274 275 276 277 278
static int bigint_bn_GetBit(HOBJECT object, int indbit)
{
	sBigInteger* pobj;
	int ind32;
	pobj = (sBigInteger*)objectThis(object);
	if (indbit < 0 || indbit >= pobj->width)
		return -1;
	ind32 = indbit / 32;
	return pobj->buf[ind32] & (1 << (indbit & 31));
}

static int bigint_bn_SetBit(HOBJECT object, int indbit, int bit)
饶先宏's avatar
饶先宏 已提交
279 280
{
	sBigInteger* pobj;
281
	int ind32;
饶先宏's avatar
饶先宏 已提交
282
	pobj = (sBigInteger*)objectThis(object);
283
	if (indbit < 0 || indbit >= pobj->width)
饶先宏's avatar
饶先宏 已提交
284
		return -1;
285 286 287 288 289
	ind32 = indbit / 32;
	if (bit != 0)
		pobj->buf[ind32] |= (1 << (indbit & 31));
	else
		pobj->buf[ind32] &= ~(1 << (indbit & 31));
饶先宏's avatar
饶先宏 已提交
290 291 292 293 294
	return 0;
}


static int bigint_bn_GetInt32(HOBJECT object, int* pvalue)
饶先宏's avatar
饶先宏 已提交
295 296 297
{ 
	sBigInteger* pobj;
	pobj = (sBigInteger*)objectThis(object);
饶先宏's avatar
饶先宏 已提交
298
	*(unsigned int*)pvalue = pobj->buf[0];
饶先宏's avatar
饶先宏 已提交
299 300 301 302 303 304 305
	return 0; 
}

static int bigint_bn_GetInt64(HOBJECT object, long long* pvalue)
{
	sBigInteger* pobj;
	pobj = (sBigInteger*)objectThis(object);
饶先宏's avatar
饶先宏 已提交
306 307
	((unsigned int *)pvalue)[0] = pobj->buf[0];
	((unsigned int *)pvalue)[1] = pobj->buf[1];
饶先宏's avatar
饶先宏 已提交
308 309 310
	return 0;
}

饶先宏's avatar
饶先宏 已提交
311
static int bigint_bn_GetUint32(HOBJECT object, unsigned int* pvalue)
饶先宏's avatar
饶先宏 已提交
312 313 314 315 316 317 318
{
	sBigInteger* pobj;
	pobj = (sBigInteger*)objectThis(object);
	*(unsigned int*)pvalue = pobj->buf[0];
	return 0;
}

饶先宏's avatar
饶先宏 已提交
319
static int bigint_bn_GetUint64(HOBJECT object, unsigned long long* pvalue)
饶先宏's avatar
饶先宏 已提交
320 321 322 323 324 325 326 327
{
	sBigInteger* pobj;
	pobj = (sBigInteger*)objectThis(object);
	((unsigned int*)pvalue)[0] = pobj->buf[0];
	((unsigned int*)pvalue)[1] = pobj->buf[1];
	return 0;
}

饶先宏's avatar
饶先宏 已提交
328 329 330 331 332 333 334 335 336 337 338 339 340
static int bigint_bn_GetStr2(sBigInteger* pobj, char* str, int buflen)
{
	int i;
	if (pobj->width < buflen - 1) {
		buflen = pobj->width;
	}
	for (i = 0; i < buflen; i++) {
		str[buflen - 1 - i] = (pobj->buf[i / CELL_WIDTH] & (1 << (i & (CELL_WIDTH-1))))? '1' : '0';
	}
	str[buflen] = '\0';
	return 0;
}

饶先宏's avatar
饶先宏 已提交
341 342 343 344
static int bigint_bn_GetStr10(sBigInteger* pobj, char* str, int buflen)
{
	int i;
	int len;
饶先宏's avatar
饶先宏 已提交
345
	unsigned int value;
饶先宏's avatar
饶先宏 已提交
346
	int sign = 0;
饶先宏's avatar
饶先宏 已提交
347 348
	int v;
	if (pobj->width > 30) {
饶先宏's avatar
饶先宏 已提交
349 350
		return -1;
	}
饶先宏's avatar
饶先宏 已提交
351 352
	v = pobj->buf[0];
	if (v < 0 && pobj->isunsigned == 0) {
饶先宏's avatar
饶先宏 已提交
353
		sign = 1;
饶先宏's avatar
饶先宏 已提交
354
		value = -v;
饶先宏's avatar
饶先宏 已提交
355
	}
饶先宏's avatar
饶先宏 已提交
356 357 358 359
	else {
		value = pobj->buf[0];
	}
	
饶先宏's avatar
饶先宏 已提交
360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381
	i = 0;
	while (value > 0) {
		int num = value % 10;
		value /= 10;
		str[i++] = num + '0';
	}
	if (i == 0)
		str[i++] = '0';
	if (sign)
		str[i++] = '-';
	str[i] = 0;
	len = i;
	for (i = 0;i<len/2;i++){
		char ch;
		ch = str[len - 1 - i];
		str[len - 1 - i] = str[i];
		str[i] = ch;
	}
	return 0;
}


饶先宏's avatar
饶先宏 已提交
382 383 384 385 386 387 388 389 390
static int bigint_bn_GetStr(HOBJECT object, int base, char* str, int buflen)
{ 
	int i;
	int bc, ac;
	char fmt[10];
	char buf[10];
	sBigInteger* pobj;
	pobj = (sBigInteger*)objectThis(object);
	str[0] = 0;
饶先宏's avatar
饶先宏 已提交
391
	bc = bigint_bn_GetWidth(object);
饶先宏's avatar
饶先宏 已提交
392 393 394 395
	if (bc == 0) {
		strcpy(str, "0");
		return 0;
	}
饶先宏's avatar
饶先宏 已提交
396 397
	if (base == 2)
		return bigint_bn_GetStr2(pobj, str, buflen);
饶先宏's avatar
饶先宏 已提交
398 399 400 401 402
	if (base == 10) {
		if (bigint_bn_GetStr10(pobj, str, buflen) == 0) {
			return 0;
		}
	}
饶先宏's avatar
饶先宏 已提交
403 404 405 406 407
	if (pobj->isunsigned)
		sprintf(str, "%d'h", bc);
	else
		sprintf(str, "%d'sh", bc);

饶先宏's avatar
饶先宏 已提交
408
	i = ((bc + (CELL_WIDTH-1)) / CELL_WIDTH) - 1;
饶先宏's avatar
饶先宏 已提交
409 410
	ac = actualwidth(pobj->buf[i]);
	ac = (ac + 7) / 8;
411
	sprintf(fmt, "%%%dx", ac);
饶先宏's avatar
饶先宏 已提交
412 413
	sprintf(buf, fmt, pobj->buf[i]);
	strcat(str, buf);
饶先宏's avatar
饶先宏 已提交
414
	for (i = ((bc + (CELL_WIDTH-1)) / CELL_WIDTH)-2; i >= 0; i--) {
饶先宏's avatar
饶先宏 已提交
415 416 417 418 419 420
		sprintf(buf, "%08x", pobj->buf[i]);
		strcat(str, buf);
	}
	return 0; 
}

饶先宏's avatar
饶先宏 已提交
421 422
static int bigint_bn_AssignInt32(HOBJECT object, int value)
{
饶先宏's avatar
饶先宏 已提交
423
	int i;
饶先宏's avatar
饶先宏 已提交
424 425
	sBigInteger* pobj;
	pobj = (sBigInteger*)objectThis(object);
饶先宏's avatar
饶先宏 已提交
426 427
	for (i = 1; i < pobj->buflen; i++)
		pobj->buf[i] = 0;
饶先宏's avatar
饶先宏 已提交
428
	pobj->buf[0] = *(unsigned int*)&value;
饶先宏's avatar
饶先宏 已提交
429 430 431
	if (pobj->isunsigned == -1)
		pobj->isunsigned = 0;
	bigint_bn_SetWidth(object, pobj->width);
饶先宏's avatar
饶先宏 已提交
432 433 434 435 436
	return 0;
}

static int bigint_bn_AssignInt64(HOBJECT object, long long value)
{
饶先宏's avatar
饶先宏 已提交
437
	int i;
饶先宏's avatar
饶先宏 已提交
438 439
	sBigInteger* pobj;
	pobj = (sBigInteger*)objectThis(object);
饶先宏's avatar
饶先宏 已提交
440 441
	for (i = 2; i < pobj->buflen; i++)
		pobj->buf[i] = 0;
饶先宏's avatar
饶先宏 已提交
442 443
	pobj->buf[0] = (*(unsigned long long*)(&value)) & CELL_MASK;
	pobj->buf[1] = ((*(unsigned long long*)(&value)) >> CELL_WIDTH) & CELL_MASK;
饶先宏's avatar
饶先宏 已提交
444 445 446
	if (pobj->isunsigned == -1)
		pobj->isunsigned = 0;
	bigint_bn_SetWidth(object, pobj->width);
饶先宏's avatar
饶先宏 已提交
447 448 449 450 451
	return 0;
}

static int bigint_bn_AssignUint32(HOBJECT object, unsigned int value)
{
饶先宏's avatar
饶先宏 已提交
452
	int i;
饶先宏's avatar
饶先宏 已提交
453 454
	sBigInteger* pobj;
	pobj = (sBigInteger*)objectThis(object);
饶先宏's avatar
饶先宏 已提交
455 456 457
	for (i = 1; i < pobj->buflen; i++)
		pobj->buf[i] = 0;

饶先宏's avatar
饶先宏 已提交
458
	pobj->buf[0] = *(unsigned int*)&value;
饶先宏's avatar
饶先宏 已提交
459 460 461
	if (pobj->isunsigned == -1)
		pobj->isunsigned = 1;
	bigint_bn_SetWidth(object, pobj->width);
饶先宏's avatar
饶先宏 已提交
462 463 464 465 466
	return 0;
}

static int bigint_bn_AssignUint64(HOBJECT object, unsigned long long value)
{
饶先宏's avatar
饶先宏 已提交
467
	int i;
饶先宏's avatar
饶先宏 已提交
468 469
	sBigInteger* pobj;
	pobj = (sBigInteger*)objectThis(object);
饶先宏's avatar
饶先宏 已提交
470 471
	for (i = 2; i < pobj->buflen; i++)
		pobj->buf[i] = 0;
饶先宏's avatar
饶先宏 已提交
472 473
	pobj->buf[0] = (*(unsigned long long*)(&value)) & CELL_MASK;
	pobj->buf[1] = ((*(unsigned long long*)(&value)) >> CELL_WIDTH) & CELL_MASK;
饶先宏's avatar
饶先宏 已提交
474 475 476
	if (pobj->isunsigned == -1)
		pobj->isunsigned = 0;
	bigint_bn_SetWidth(object, pobj->width);
饶先宏's avatar
饶先宏 已提交
477 478 479
	return 0;
}

饶先宏's avatar
饶先宏 已提交
480 481 482 483 484 485 486 487 488 489
enum TOKEN_STATE {
	TOKEN_INITIAL,
	TOKEN_NUM,
	TOKEN_BASE,
	TOKEN_BIN,
	TOKEN_OCT,
	TOKEN_DEC,
	TOKEN_HEX
};

饶先宏's avatar
饶先宏 已提交
490 491 492
#define MAXNUMWIDTH (1 << 30)

static int bigint_bn_AssignStr(HOBJECT object, const char* str, const char **nstr, int autowidth)
饶先宏's avatar
饶先宏 已提交
493
{ 
饶先宏's avatar
饶先宏 已提交
494
	int width, objwidth;
饶先宏's avatar
饶先宏 已提交
495 496 497 498 499
	enum TOKEN_STATE state;
	const char* strt = str;
	int numvalid = 0;
	sBigInteger* pobj;
	pobj = (sBigInteger*)objectThis(object);
饶先宏's avatar
饶先宏 已提交
500 501 502 503
	width = -1;
	objwidth = pobj->width;
	if (autowidth == 0 && objwidth <= 0)
		return -1;
饶先宏's avatar
饶先宏 已提交
504 505
	pobj->isunsigned = 1;
	bigint_bn_SetWidth(object, 32);
饶先宏's avatar
饶先宏 已提交
506
	state = TOKEN_INITIAL;
507 508
	if (nstr != NULL)
		*nstr = strt;
饶先宏's avatar
饶先宏 已提交
509 510 511 512 513 514 515 516
	while (*strt != 0) {
		int ch = *strt;
		switch (state) {
		case TOKEN_INITIAL: {
			if (ch == '\'') {
				state = TOKEN_BASE;
			}
			else if (ch >= '0' && ch <= '9') {
517
				bigint_bn_AssignInt32(object, ch - '0');
饶先宏's avatar
饶先宏 已提交
518 519 520 521 522 523
				numvalid = 1;
				state = TOKEN_NUM;
			}
		} break;
		case TOKEN_NUM: {
			if (ch >= '0' && ch <= '9') {
饶先宏's avatar
饶先宏 已提交
524 525 526 527 528 529
				if (pobj->buf[pobj->buflen - 1] > (1 << 27)) {
					int w;
					w = pobj->width * 2;
					if (w > MAXNUMWIDTH) {
						w = MAXNUMWIDTH;
					}
饶先宏's avatar
饶先宏 已提交
530
					if (0 != bigint_bn_SetWidth(object, w)) {
531 532
						if (nstr != NULL)
							*nstr = strt;
饶先宏's avatar
饶先宏 已提交
533 534 535
						return -1;
					}
				}
536 537
				bigint_bn_MulInt32(object, object, 10);
				bigint_bn_AddInt32(object, object, ch - '0');
饶先宏's avatar
饶先宏 已提交
538 539
			}
			else if (ch == '\'') {
饶先宏's avatar
饶先宏 已提交
540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555
				int i;
				for (i = pobj->buflen - 1; i > 0; i--) {
					if (pobj->buf[i] != 0) {
						/* too large width of a number */
						width = MAXNUMWIDTH;
						break;
					}
				}
				if (width == -1) {
					if (pobj->buf[0] > MAXNUMWIDTH) {
						width = MAXNUMWIDTH;
					}
					else {
						width = pobj->buf[0];
					}
				}
饶先宏's avatar
饶先宏 已提交
556
				pobj->isunsigned = 1;
饶先宏's avatar
饶先宏 已提交
557
				state = TOKEN_BASE;
饶先宏's avatar
饶先宏 已提交
558 559 560
				if (width == 0)
					width = -1;
				else
饶先宏's avatar
饶先宏 已提交
561
				if (0 != bigint_bn_SetWidth(object, width)) {
562 563
					if (nstr != NULL)
						*nstr = strt;
饶先宏's avatar
饶先宏 已提交
564
				}
饶先宏's avatar
饶先宏 已提交
565
				objwidth = width;
饶先宏's avatar
饶先宏 已提交
566 567 568
				numvalid = 0;
			}
			else {
饶先宏's avatar
饶先宏 已提交
569
				pobj->isunsigned = 0;
饶先宏's avatar
饶先宏 已提交
570 571 572 573
				goto lastnum;
			}
		}break;
		case TOKEN_BASE: {
饶先宏's avatar
饶先宏 已提交
574
			if (ch == 's' || ch == 'S') {
饶先宏's avatar
饶先宏 已提交
575
				pobj->isunsigned = 0;
饶先宏's avatar
饶先宏 已提交
576 577
			}
			else if (ch == 'b' || ch == 'B') {
578
				bigint_bn_AssignInt32(object, 0);
饶先宏's avatar
饶先宏 已提交
579 580 581
				state = TOKEN_BIN;
			}
			else if (ch == 'h' || ch == 'H') {
582
				bigint_bn_AssignInt32(object, 0);
饶先宏's avatar
饶先宏 已提交
583 584 585
				state = TOKEN_HEX;
			}
			else if (ch == 'o' || ch == 'O') {
586
				bigint_bn_AssignInt32(object, 0);
饶先宏's avatar
饶先宏 已提交
587 588 589
				state = TOKEN_OCT;
			}
			else if (ch == 'd' || ch == 'D') {
590
				bigint_bn_AssignInt32(object, 0);
饶先宏's avatar
饶先宏 已提交
591 592 593 594 595 596
				state = TOKEN_DEC;
			}
			else if (ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n') {

			}
			else {
597 598
				if (nstr != NULL)
					*nstr = strt;
饶先宏's avatar
饶先宏 已提交
599 600 601 602 603
				return -1;
			}
		}break;
		case TOKEN_BIN: {
			if (ch == '0' || ch == '1') {
饶先宏's avatar
饶先宏 已提交
604 605 606 607 608 609 610
				if (autowidth && (width == -1)) {
					if (pobj->buf[pobj->buflen - 1] > (1 << 27)) {
						int w;
						w = pobj->width * 2;
						if (w > MAXNUMWIDTH) {
							w = MAXNUMWIDTH;
						}
饶先宏's avatar
饶先宏 已提交
611
						if (0 != bigint_bn_SetWidth(object, w)) {
612 613
							if (nstr != NULL)
								*nstr = strt;
饶先宏's avatar
饶先宏 已提交
614
							return -1;
615
						}
饶先宏's avatar
饶先宏 已提交
616 617
					}
				}
饶先宏's avatar
饶先宏 已提交
618 619
				bigint_bn_MulUint32(object, object, 2);
				bigint_bn_AddUint32(object, object, ch - '0');
饶先宏's avatar
饶先宏 已提交
620 621 622 623 624 625 626 627 628 629
				numvalid = 1;
			}
			else if (ch == '_') {
			}
			else {
				goto lastnum;
			}
		}break;
		case TOKEN_OCT: {
			if (ch >= '0' && ch <= '7') {
饶先宏's avatar
饶先宏 已提交
630 631 632 633 634 635 636
				if (autowidth && (width == -1)) {
					if (pobj->buf[pobj->buflen - 1] > (1 << 27)) {
						int w;
						w = pobj->width * 2;
						if (w > MAXNUMWIDTH) {
							w = MAXNUMWIDTH;
						}
饶先宏's avatar
饶先宏 已提交
637
						if (0 != bigint_bn_SetWidth(object, w)) {
638 639
							if (nstr != NULL)
								*nstr = strt;
饶先宏's avatar
饶先宏 已提交
640
							return -1;
641
						}
饶先宏's avatar
饶先宏 已提交
642 643
					}
				}
饶先宏's avatar
饶先宏 已提交
644 645
				bigint_bn_MulUint32(object, object, 8);
				bigint_bn_AddUint32(object, object, ch - '0');
饶先宏's avatar
饶先宏 已提交
646 647 648 649 650 651 652 653 654 655
				numvalid = 1;
			}
			else if (ch == '_') {
			}
			else {
				goto lastnum;
			}
		}break;
		case TOKEN_DEC: {
			if (ch >= '0' && ch <= '9') {
饶先宏's avatar
饶先宏 已提交
656 657 658 659 660 661 662
				if (autowidth && (width == -1)) {
					if (pobj->buf[pobj->buflen - 1] > (1 << 27)) {
						int w;
						w = pobj->width * 2;
						if (w > MAXNUMWIDTH) {
							w = MAXNUMWIDTH;
						}
饶先宏's avatar
饶先宏 已提交
663
						if (0 != bigint_bn_SetWidth(object, w)) {
664 665
							if (nstr != NULL)
								*nstr = strt;
饶先宏's avatar
饶先宏 已提交
666
							return -1;
667
						}
饶先宏's avatar
饶先宏 已提交
668 669
					}
				}
饶先宏's avatar
饶先宏 已提交
670 671
				bigint_bn_MulUint32(object, object, 10);
				bigint_bn_AddUint32(object, object, ch - '0');
饶先宏's avatar
饶先宏 已提交
672 673 674 675 676 677 678 679 680
				numvalid = 1;
			}
			else {
				goto lastnum;
			}
		}break;
		case TOKEN_HEX: {
			if ((ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'f') || (ch >= 'A' && ch <= 'F')) {
				numvalid = 1;
饶先宏's avatar
饶先宏 已提交
681 682 683 684 685 686 687
				if (autowidth && (width == -1)) {
					if (pobj->buf[pobj->buflen - 1] > (1 << 27)) {
						int w;
						w = pobj->width * 2;
						if (w > MAXNUMWIDTH) {
							w = MAXNUMWIDTH;
						}
饶先宏's avatar
饶先宏 已提交
688
						if (0 != bigint_bn_SetWidth(object, w)) {
689 690
							if (nstr != NULL)
								*nstr = strt;
饶先宏's avatar
饶先宏 已提交
691
							return -1;
692
						}
饶先宏's avatar
饶先宏 已提交
693 694
					}
				}
饶先宏's avatar
饶先宏 已提交
695
				bigint_bn_MulUint32(object, object, 16);
饶先宏's avatar
饶先宏 已提交
696
				if (ch > '0' && ch <= '9')
饶先宏's avatar
饶先宏 已提交
697
					bigint_bn_AddUint32(object, object, ch - '0');
饶先宏's avatar
饶先宏 已提交
698
				else if (ch >= 'a' && ch <= 'f')
饶先宏's avatar
饶先宏 已提交
699
					bigint_bn_AddUint32(object, object, ch - 'a' + 10);
饶先宏's avatar
饶先宏 已提交
700
				else if (ch >= 'A' && ch <= 'F')
饶先宏's avatar
饶先宏 已提交
701
					bigint_bn_AddUint32(object, object, ch - 'A' + 10);
饶先宏's avatar
饶先宏 已提交
702 703 704 705 706 707 708 709 710 711 712
			}
			else if (ch == '_') {
			}
			else {
				goto lastnum;
			}

		}break;
		}
		strt++;
	}
713 714 715
	if (numvalid == 0) {
		if (nstr != NULL)
			*nstr = strt;
饶先宏's avatar
饶先宏 已提交
716
		return -1;
717
	}
饶先宏's avatar
饶先宏 已提交
718
lastnum:
饶先宏's avatar
饶先宏 已提交
719 720
	if (nstr != NULL)
		*nstr = strt;
饶先宏's avatar
饶先宏 已提交
721 722 723 724 725 726 727 728 729 730 731 732
	if (autowidth && (width == -1)) {
		int i;
		width = 0;
		for (i = pobj->buflen - 1; i >= 0; i--) {
			if (pobj->buf[i] != 0) {
				width = actualwidth(pobj->buf[i]);
				width += i * CELL_WIDTH;
				break;
			}
		}
		if (width == 0)
			width = 1;
饶先宏's avatar
饶先宏 已提交
733
	//	if (pobj->isunsigned == 0)
饶先宏's avatar
饶先宏 已提交
734 735 736
			width++;
	}
	else {
饶先宏's avatar
饶先宏 已提交
737
		width = objwidth;
饶先宏's avatar
饶先宏 已提交
738
	}
饶先宏's avatar
饶先宏 已提交
739
	bigint_bn_SetWidth(object, width);
饶先宏's avatar
饶先宏 已提交
740 741 742
	return 0;
}

饶先宏's avatar
饶先宏 已提交
743
static int bigint_bn_Clone(HOBJECT object, HOBJECT src)
饶先宏's avatar
饶先宏 已提交
744 745
{ 
	sBigInteger* pobj;
746
	IBigNumber** numsrc;
饶先宏's avatar
饶先宏 已提交
747
	int i;
748 749
	int width;
	int buflen;
饶先宏's avatar
饶先宏 已提交
750
	pobj = (sBigInteger*)objectThis(object);
751 752 753 754 755
	if (EIID_OK != objectQueryInterface(src, IID_BIGNUMBER, (void**)&numsrc))
		return -1;
	width = objectCall0(numsrc, GetWidth);
	if (width <= 0) {
		objectRelease(numsrc);
饶先宏's avatar
饶先宏 已提交
756 757
		return -1;
	}
758 759 760 761
	buflen = (width + CELL_WIDTH - 1) / CELL_WIDTH;
	if (buflen < 2)
		buflen = 2;
	if (pobj->buflen < buflen) {
饶先宏's avatar
饶先宏 已提交
762
		unsigned int* buf;
763 764 765
		buf = (unsigned int*)malloc(buflen * (CELL_WIDTH / 8));
		if (buf == NULL) {
			objectRelease(numsrc);
饶先宏's avatar
饶先宏 已提交
766
			return -2;
767
		}
饶先宏's avatar
饶先宏 已提交
768 769 770
		free(pobj->buf);
		pobj->buf = buf;
	}
771 772
	pobj->buflen = buflen;
	pobj->width = width;
饶先宏's avatar
饶先宏 已提交
773
	pobj->isunsigned = objectCall0(numsrc, IsUnsigned);
774 775 776 777
	for (i = 0; i < pobj->buflen; i++) {
		objectCall2(numsrc, GetBits32, i, &pobj->buf[i]);
	}
	objectRelease(numsrc);
饶先宏's avatar
饶先宏 已提交
778 779 780
	return 0;
}

饶先宏's avatar
饶先宏 已提交
781
static int bigint_bn_CloneSubBits(HOBJECT object, HOBJECT src, int from, int width)
饶先宏's avatar
饶先宏 已提交
782
{
783 784
	if (from < 0 || width <= 0)
		return -1;
785 786 787 788
#if HDL4SEDEBUG
	char buf[60];
	bigint_bn_GetStr(src, 16, buf, 60);
#endif
饶先宏's avatar
饶先宏 已提交
789 790
	bigint_bn_SetUnsigned(object, 1);
	bigint_bn_SetWidth(object, width);
791 792 793 794
	bigint_bn_SHR(object, src, from);
#if HDL4SEDEBUG
	bigint_bn_GetStr(object, 16, buf, 60);
#endif
饶先宏's avatar
饶先宏 已提交
795
	bigint_bn_SetWidth(object, width);
796 797 798
#if HDL4SEDEBUG
	bigint_bn_GetStr(object, 16, buf, 60);
#endif
饶先宏's avatar
饶先宏 已提交
799 800 801
	return 0;
}

饶先宏's avatar
饶先宏 已提交
802 803
static int bigint_bn_Assign(HOBJECT object, HOBJECT src)
{
饶先宏's avatar
饶先宏 已提交
804
	int width, isunsigned;
805
	width = bigint_bn_GetWidth(object);
饶先宏's avatar
饶先宏 已提交
806
	isunsigned = bigint_bn_IsUnsigned(object);
807
	bigint_bn_Clone(object, src);
饶先宏's avatar
饶先宏 已提交
808 809
	bigint_bn_SetUnsigned(object, isunsigned);
	bigint_bn_SetWidth(object, width);
饶先宏's avatar
饶先宏 已提交
810 811 812 813 814
	return 0;
}

static int bigint_bn_AssignSubBits(HOBJECT object, HOBJECT src, int from, int width)
{
815
	int objwidth;
816 817 818 819
#if HDL4SEDEBUG
	char buf[60];
	bigint_bn_GetStr(src, 16, buf, 60);
#endif
820
	objwidth = bigint_bn_GetWidth(object);
饶先宏's avatar
饶先宏 已提交
821 822
	bigint_bn_CloneSubBits(object, src, from, width);
	bigint_bn_SetWidth(object, objwidth);
823 824 825
#if HDL4SEDEBUG
	bigint_bn_GetStr(object, 16, buf, 60);
#endif
饶先宏's avatar
饶先宏 已提交
826 827 828
	return 0;
}

829
static int bigint_bn_AddInt32(HOBJECT object, HOBJECT src, int value)
饶先宏's avatar
饶先宏 已提交
830 831 832
{ 
	unsigned long long temp;
	int ind;
饶先宏's avatar
饶先宏 已提交
833 834
	unsigned int v, vs, widthsrc, width;
	int objunsigned, srcunsigned;
饶先宏's avatar
饶先宏 已提交
835
	sBigInteger* pobj;
836
	IBigNumber** numsrc;
饶先宏's avatar
饶先宏 已提交
837
	pobj = (sBigInteger*)objectThis(object);
838 839 840
	if (EIID_OK != objectQueryInterface(src, IID_BIGNUMBER, (void**)&numsrc))
		return -1;
	widthsrc = objectCall0(numsrc, GetWidth);
饶先宏's avatar
饶先宏 已提交
841 842 843 844 845 846 847
	srcunsigned = objectCall0(numsrc, IsUnsigned);
	objunsigned = pobj->isunsigned;

	width = pobj->width;
	if (width < widthsrc)
		width = widthsrc;
	
848
	//objectCall1(numsrc, SetUnsigned, 0);
饶先宏's avatar
饶先宏 已提交
849 850
	objectCall1(numsrc, SetWidth, width);
	
851
	//bigint_bn_SetUnsigned(object, 0);
饶先宏's avatar
饶先宏 已提交
852 853
	bigint_bn_SetWidth(object, width);

854 855
	objectCall2(numsrc, GetBits32, 0, &vs);
	temp = vs;
饶先宏's avatar
饶先宏 已提交
856 857 858 859 860 861 862
	temp += *(unsigned int*)&value;
	pobj->buf[0] = temp & CELL_MASK;
	temp >>= CELL_WIDTH;
	ind = 1;
	v = 0;
	if (value < 0)
		v = CELL_MASK;
饶先宏's avatar
饶先宏 已提交
863
	while (ind < pobj->buflen) {
饶先宏's avatar
饶先宏 已提交
864
		temp += v;
865
		if (0 != objectCall2(numsrc, GetBits32, ind, &vs))
饶先宏's avatar
饶先宏 已提交
866 867
			vs = CELL_MASK;
		temp += vs;
饶先宏's avatar
饶先宏 已提交
868 869 870 871
		pobj->buf[ind] = temp & CELL_MASK;
		temp >>= CELL_WIDTH;
		ind++;
	}
饶先宏's avatar
饶先宏 已提交
872 873 874 875
	objectCall1(numsrc, SetUnsigned, srcunsigned);
	objectCall1(numsrc, SetWidth, widthsrc);
	bigint_bn_SetUnsigned(object, objunsigned);
	bigint_bn_SetWidth(object, pobj->width);
饶先宏's avatar
饶先宏 已提交
876 877 878
	return 0;
}

879
static int bigint_bn_SubInt32(HOBJECT object, HOBJECT src, int value)
饶先宏's avatar
饶先宏 已提交
880
{
881
	return bigint_bn_AddInt32(object, src, -value);
饶先宏's avatar
饶先宏 已提交
882 883
}

884
static int bigint_bn_MulInt32(HOBJECT object, HOBJECT src, int value)
饶先宏's avatar
饶先宏 已提交
885
{
饶先宏's avatar
饶先宏 已提交
886
	IBigNumber ** temp;
饶先宏's avatar
饶先宏 已提交
887
	temp = bigintegerCreate(32);
饶先宏's avatar
饶先宏 已提交
888
	bigint_bn_SetUnsigned(temp, 0);
889 890
	bigint_bn_AssignInt32(temp, value);
	bigint_bn_Mul(object, src, temp);
饶先宏's avatar
饶先宏 已提交
891
	objectRelease(temp);
饶先宏's avatar
饶先宏 已提交
892 893 894
	return 0;
}

895
static int bigint_bn_DivInt32(HOBJECT object, HOBJECT src, int value)
饶先宏's avatar
饶先宏 已提交
896
{
饶先宏's avatar
饶先宏 已提交
897
	IBigNumber** temp;
898
	temp = bigintegerCreate(32);
饶先宏's avatar
饶先宏 已提交
899
	bigint_bn_SetUnsigned(temp, 0);
900 901 902
	bigint_bn_AssignInt32(temp, value);
	bigint_bn_Div(object, src, temp);
	objectRelease(temp);
饶先宏's avatar
饶先宏 已提交
903 904 905
	return 0;
}

906
static int bigint_bn_ModInt32(HOBJECT object, HOBJECT src, int value)
饶先宏's avatar
饶先宏 已提交
907
{
饶先宏's avatar
饶先宏 已提交
908
	IBigNumber** temp;
909
	temp = bigintegerCreate(32);
饶先宏's avatar
饶先宏 已提交
910
	bigint_bn_SetUnsigned(temp, 0);
911 912 913
	bigint_bn_AssignInt32(temp, value);
	bigint_bn_Mod(object, src, temp);
	objectRelease(temp);
饶先宏's avatar
饶先宏 已提交
914 915 916
	return 0;
}

饶先宏's avatar
饶先宏 已提交
917 918 919 920
static int bigint_bn_PowInt32(HOBJECT object, HOBJECT src, int value)
{
	IBigNumber** temp;
	temp = bigintegerCreate(32);
饶先宏's avatar
饶先宏 已提交
921
	bigint_bn_SetUnsigned(temp, 0);
饶先宏's avatar
饶先宏 已提交
922 923 924 925 926 927
	bigint_bn_AssignInt32(temp, value);
	bigint_bn_Pow(object, src, temp);
	objectRelease(temp);
	return 0;
}

928
static int bigint_bn_AddUint32(HOBJECT object, HOBJECT src, unsigned int value)
饶先宏's avatar
饶先宏 已提交
929
{
饶先宏's avatar
饶先宏 已提交
930
	return bigint_bn_AddInt32(object, src, value);
饶先宏's avatar
饶先宏 已提交
931 932
}

933
static int bigint_bn_SubUint32(HOBJECT object, HOBJECT src, unsigned int value)
饶先宏's avatar
饶先宏 已提交
934
{
饶先宏's avatar
饶先宏 已提交
935 936
	bigint_bn_AssignUint32(object, value);
	bigint_bn_Neg(object, object);
饶先宏's avatar
饶先宏 已提交
937
	bigint_bn_Add(object, object, src);
938
	return 0;
饶先宏's avatar
饶先宏 已提交
939 940
}

941
static int bigint_bn_MulUint32(HOBJECT object, HOBJECT src, unsigned int value)
饶先宏's avatar
饶先宏 已提交
942
{
饶先宏's avatar
饶先宏 已提交
943
	IBigNumber** temp;
饶先宏's avatar
饶先宏 已提交
944
	temp = bigintegerCreate(32);
饶先宏's avatar
饶先宏 已提交
945
	bigint_bn_SetUnsigned(temp, 1);
946
	bigint_bn_AssignUint32(temp, value);
饶先宏's avatar
饶先宏 已提交
947
	bigint_bn_Mul(object, src, temp);
饶先宏's avatar
饶先宏 已提交
948 949 950 951
	objectRelease(temp);
	return 0;
}

952
static int bigint_bn_DivUint32(HOBJECT object, HOBJECT src, unsigned int value)
饶先宏's avatar
饶先宏 已提交
953
{
饶先宏's avatar
饶先宏 已提交
954
	IBigNumber** temp;
955
	temp = bigintegerCreate(32);
饶先宏's avatar
饶先宏 已提交
956
	bigint_bn_SetUnsigned(temp, 1);
957
	bigint_bn_AssignUint32(temp, value);
饶先宏's avatar
饶先宏 已提交
958
	bigint_bn_Div(object, src, temp);
959
	objectRelease(temp);
饶先宏's avatar
饶先宏 已提交
960 961 962
	return 0;
}

963
static int bigint_bn_ModUint32(HOBJECT object, HOBJECT src, unsigned int value)
饶先宏's avatar
饶先宏 已提交
964
{
饶先宏's avatar
饶先宏 已提交
965
	IBigNumber** temp;
966
	temp = bigintegerCreate(32);
饶先宏's avatar
饶先宏 已提交
967
	bigint_bn_SetUnsigned(temp, 1);
968
	bigint_bn_AssignUint32(temp, value);
饶先宏's avatar
饶先宏 已提交
969
	bigint_bn_Mod(object, src, temp);
970
	objectRelease(temp);
饶先宏's avatar
饶先宏 已提交
971 972 973
	return 0;
}

饶先宏's avatar
饶先宏 已提交
974 975 976 977
static int bigint_bn_PowUint32(HOBJECT object, HOBJECT src, unsigned int value)
{
	IBigNumber** temp;
	temp = bigintegerCreate(32);
饶先宏's avatar
饶先宏 已提交
978
	bigint_bn_SetUnsigned(temp, 1);
饶先宏's avatar
饶先宏 已提交
979
	bigint_bn_AssignUint32(temp, value);
饶先宏's avatar
饶先宏 已提交
980
	bigint_bn_Pow(object, src, temp);
饶先宏's avatar
饶先宏 已提交
981 982 983 984
	objectRelease(temp);
	return 0;
}

饶先宏's avatar
饶先宏 已提交
985 986
static int bigint_bn_Add(HOBJECT object, HOBJECT src0, HOBJECT src1)
{
饶先宏's avatar
饶先宏 已提交
987
	unsigned long long temp;
饶先宏's avatar
饶先宏 已提交
988
	sBigInteger* pobj;
989 990
	IBigNumber** psrc0;
	IBigNumber** psrc1;
饶先宏's avatar
饶先宏 已提交
991 992
	int widthobj, widthsrc0, widthsrc1, width;
	int objunsigned, src0unsigned, src1unsigned;
饶先宏's avatar
饶先宏 已提交
993
	int i;
饶先宏's avatar
饶先宏 已提交
994
	pobj = (sBigInteger*)objectThis(object);
995 996 997 998 999
	if (EIID_OK != objectQueryInterface(src0, IID_BIGNUMBER, (void**)&psrc0)) {
		return -1;
	}
	if (EIID_OK != objectQueryInterface(src1, IID_BIGNUMBER, (void**)&psrc1)) {
		objectRelease(psrc0);
饶先宏's avatar
饶先宏 已提交
1000 1001 1002
		return -1;
	}
	widthobj = pobj->width;
1003 1004
	widthsrc0 = objectCall0(psrc0, GetWidth);
	widthsrc1 = objectCall0(psrc1, GetWidth);
饶先宏's avatar
饶先宏 已提交
1005 1006 1007 1008 1009

	objunsigned = pobj->isunsigned;
	src0unsigned = objectCall0(psrc0, IsUnsigned);
	src1unsigned = objectCall0(psrc1, IsUnsigned);

1010 1011 1012
//	bigint_bn_SetUnsigned(object, 0);
//	objectCall1(psrc0, SetUnsigned, 0);
//	objectCall1(psrc1, SetUnsigned, 0);
饶先宏's avatar
饶先宏 已提交
1013 1014 1015 1016 1017 1018 1019 1020 1021

	width = widthsrc0;
	if (width < widthsrc1)
		width = widthsrc1;
	if (width < widthobj)
		width = widthobj;
	objectCall1(psrc0, SetWidth, width);
	objectCall1(psrc1, SetWidth, width);
	bigint_bn_SetWidth(object, width);
饶先宏's avatar
饶先宏 已提交
1022 1023
	temp = 0;
	for (i = 0; i < pobj->buflen; i++) {
1024 1025 1026 1027 1028
		unsigned int src0value, src1value;
		objectCall2(psrc0, GetBits32, i, &src0value);
		objectCall2(psrc1, GetBits32, i, &src1value);
		temp += src0value;
		temp += src1value;
饶先宏's avatar
饶先宏 已提交
1029 1030 1031
		pobj->buf[i] = temp & CELL_MASK;
		temp >>= CELL_WIDTH;
	}
饶先宏's avatar
饶先宏 已提交
1032 1033 1034
	bigint_bn_SetUnsigned(object, objunsigned);
	objectCall1(psrc0, SetUnsigned, src0unsigned);
	objectCall1(psrc1, SetUnsigned, src1unsigned);
饶先宏's avatar
饶先宏 已提交
1035
	bigint_bn_SetWidth(object, widthobj);
饶先宏's avatar
饶先宏 已提交
1036 1037
	objectCall1(psrc0, SetWidth, widthsrc0);
	objectCall1(psrc1, SetWidth, widthsrc1);
1038 1039
	objectRelease(psrc0);
	objectRelease(psrc1);
饶先宏's avatar
饶先宏 已提交
1040 1041 1042
	return 0;
}

饶先宏's avatar
饶先宏 已提交
1043
static int bigint_bn_Sub(HOBJECT object, HOBJECT src0, HOBJECT src1)
饶先宏's avatar
饶先宏 已提交
1044
{ 
饶先宏's avatar
饶先宏 已提交
1045
	IBigNumber** temp = NULL;
饶先宏's avatar
饶先宏 已提交
1046 1047
	int ret;
	temp = bigintegerCreate(32);
1048 1049 1050 1051 1052
	sBigInteger* pobj, * psrc0, * psrc1, * ptemp;
	pobj = objectThis(object);
	psrc0 = objectThis(src0);
	psrc1 = objectThis(src1);
	ptemp = objectThis(temp);	
饶先宏's avatar
饶先宏 已提交
1053
	objectCall1(temp, Clone, src1);
1054
	objectCall1(temp, SetUnsigned, 0);
饶先宏's avatar
饶先宏 已提交
1055
	if (EIID_OK != bigint_bn_Neg(temp, temp))
1056
		return -1;
饶先宏's avatar
饶先宏 已提交
1057
	ret = bigint_bn_Add(object, src0, temp);
饶先宏's avatar
饶先宏 已提交
1058
retresult:
饶先宏's avatar
饶先宏 已提交
1059
	return ret;
饶先宏's avatar
饶先宏 已提交
1060 1061
}

饶先宏's avatar
饶先宏 已提交
1062 1063
static int bigint_bn_Mul(HOBJECT object, HOBJECT src0, HOBJECT src1)
{
饶先宏's avatar
饶先宏 已提交
1064
	sBigInteger* pobj;
1065 1066
	IBigNumber** psrc0;
	IBigNumber** psrc1;
饶先宏's avatar
饶先宏 已提交
1067
	unsigned int* buf;
饶先宏's avatar
饶先宏 已提交
1068 1069
	int widthobj, widthsrc0, widthsrc1, width;
	int objunsigned, src0unsigned, src1unsigned;
饶先宏's avatar
饶先宏 已提交
1070 1071
	int i, j;
	pobj = (sBigInteger*)objectThis(object);
1072
	if (EIID_OK != objectQueryInterface(src0, IID_BIGNUMBER, (void**)&psrc0)) {
饶先宏's avatar
饶先宏 已提交
1073 1074
		return -1;
	}
1075 1076 1077
	if (EIID_OK != objectQueryInterface(src1, IID_BIGNUMBER, (void**)&psrc1)) {
		objectRelease(psrc0);
		return -1;
饶先宏's avatar
饶先宏 已提交
1078
	}
饶先宏's avatar
饶先宏 已提交
1079
	widthobj = pobj->width;
1080 1081
	widthsrc0 = objectCall0(psrc0, GetWidth);
	widthsrc1 = objectCall0(psrc1, GetWidth);
饶先宏's avatar
饶先宏 已提交
1082 1083 1084 1085 1086

	objunsigned = pobj->isunsigned;
	src0unsigned = objectCall0(psrc0, IsUnsigned);
	src1unsigned = objectCall0(psrc1, IsUnsigned);

1087 1088 1089
//	bigint_bn_SetUnsigned(object, 0);
//	objectCall1(psrc0, SetUnsigned, 0);
//	objectCall1(psrc1, SetUnsigned, 0);
饶先宏's avatar
饶先宏 已提交
1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102

	width = widthobj;
	if (width < widthsrc0)
		width = widthsrc0;
	if (width < widthsrc1)
		width = widthsrc1;

	objectCall1(psrc0, SetWidth, width);
	objectCall1(psrc1, SetWidth, width);
	bigint_bn_SetWidth(object,width);
	
	buf = (unsigned int *)malloc(pobj->buflen * sizeof(unsigned int));
	if (buf == NULL)
1103
		return -1;
饶先宏's avatar
饶先宏 已提交
1104 1105 1106 1107 1108

	for (i = 0; i < pobj->buflen; i++)
		buf[i] = 0;
	for (i = 0; i < pobj->buflen; i++) {
		unsigned long long addin;
1109 1110
		unsigned long long m0, m1;
		unsigned int m0s, m1s;
饶先宏's avatar
饶先宏 已提交
1111
		addin = 0;
1112 1113
		objectCall2(psrc0, GetBits32, i, &m0s);
		m0 = m0s;
饶先宏's avatar
饶先宏 已提交
1114
		for (j = 0; j < pobj->buflen - i; j++) {
1115 1116
			objectCall2(psrc1, GetBits32, j, &m1s);
			m1 = m1s;
饶先宏's avatar
饶先宏 已提交
1117
			m1 = m0 * m1 + addin + buf[i + j];
1118 1119
			buf[i + j] = m1 & CELL_MASK;
			addin = m1 >> CELL_WIDTH;
饶先宏's avatar
饶先宏 已提交
1120 1121 1122 1123
		}
	}
	free(pobj->buf);
	pobj->buf = buf;
饶先宏's avatar
饶先宏 已提交
1124 1125 1126 1127 1128

	bigint_bn_SetUnsigned(object, objunsigned);
	objectCall1(psrc0, SetUnsigned, src0unsigned);
	objectCall1(psrc1, SetUnsigned, src1unsigned);

饶先宏's avatar
饶先宏 已提交
1129
	bigint_bn_SetWidth(object, widthobj);
饶先宏's avatar
饶先宏 已提交
1130 1131
	objectCall1(psrc0, SetWidth, widthsrc0);
	objectCall1(psrc1, SetWidth, widthsrc1);
1132 1133
	objectRelease(psrc0);
	objectRelease(psrc1);
饶先宏's avatar
饶先宏 已提交
1134 1135 1136 1137 1138 1139 1140
	return 0;
}

static int bigint_bn_Div(HOBJECT object, HOBJECT src0, HOBJECT src1)
{ 
	sBigInteger* pobj;
	pobj = (sBigInteger*)objectThis(object);
1141
	NOTIMPL;
饶先宏's avatar
饶先宏 已提交
1142 1143 1144 1145 1146 1147 1148
	return 0;
}

static int bigint_bn_Mod(HOBJECT object, HOBJECT src0, HOBJECT src1)
{
	sBigInteger* pobj;
	pobj = (sBigInteger*)objectThis(object);
1149
	NOTIMPL;
饶先宏's avatar
饶先宏 已提交
1150 1151 1152
	return 0;
}

饶先宏's avatar
饶先宏 已提交
1153 1154 1155 1156 1157 1158 1159 1160 1161
static int bigint_bn_Pow(HOBJECT object, HOBJECT src0, HOBJECT src1)
{
	sBigInteger* pobj;
	pobj = (sBigInteger*)objectThis(object);
	NOTIMPL;
	return 0;
}


1162
static int bigint_bn_Neg(HOBJECT object, HOBJECT src)
饶先宏's avatar
饶先宏 已提交
1163 1164
{
	/* 反码加一 */
1165 1166
	bigint_bn_Not(object, src);
	bigint_bn_AddInt32(object, object, 1);
饶先宏's avatar
饶先宏 已提交
1167 1168
	return 0;
}
1169 1170 1171

static int bigint_bn_Abs(HOBJECT object, HOBJECT src)
{
1172 1173 1174 1175
	if (bigint_bn_IsNeg(src))
		bigint_bn_Neg(object, src);
	else
		bigint_bn_Assign(object, src);
1176 1177 1178 1179 1180
	return 0;
}

static int bigint_bn_IsGT(HOBJECT object, HOBJECT src)
{
1181
	return !bigint_bn_IsLE(object, src);
1182 1183 1184 1185
}

static int bigint_bn_IsGE(HOBJECT object, HOBJECT src)
{
1186
	return !bigint_bn_IsLT(object, src);
饶先宏's avatar
饶先宏 已提交
1187 1188
}

1189
static int bigint_bn_IsLT(HOBJECT object, HOBJECT src)
饶先宏's avatar
饶先宏 已提交
1190
{
1191 1192 1193 1194
	IBigNumber** numobj;
	IBigNumber** numsrc;
	IBigNumber** numsub;
	int ret;
1195

1196
	int i, buflen, widthobj, widthsrc, width, isunsignedobj, isunsignedsrc;
饶先宏's avatar
饶先宏 已提交
1197

饶先宏's avatar
饶先宏 已提交
1198 1199 1200 1201 1202 1203 1204 1205
	sBigInteger* pobj, * psrc;
	pobj = objectThis(object);
	psrc = objectThis(src);

#if HDL4SEDEBUG
	bigint_bn_GetStr(object, 16, __debug_buf, sizeof(__debug_buf));
	bigint_bn_GetStr(src, 16, __debug_buf, sizeof(__debug_buf));
#endif
1206 1207 1208 1209 1210 1211
	
	if (0 != objectQueryInterface(object, IID_BIGNUMBER, &numobj))
		return -1;
	if (0 != objectQueryInterface(src, IID_BIGNUMBER, &numsrc)) {
		objectRelease(numobj);
		return -1;
饶先宏's avatar
饶先宏 已提交
1212
	}
1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225

	widthobj = objectCall0(numobj, GetWidth);
	widthsrc = objectCall0(numsrc, GetWidth);
	isunsignedobj = objectCall0(numobj, IsUnsigned);
	isunsignedsrc = objectCall0(numsrc, IsUnsigned);

	width = widthobj;
	if (width < widthsrc)
		width = widthsrc;

	numsub = bigintegerCreate(width);
	objectCall1(numsub, SetUnsigned, 0);
	objectCall2(numsub, Sub, object, src);
饶先宏's avatar
饶先宏 已提交
1226 1227 1228 1229
#if HDL4SEDEBUG
	bigint_bn_GetStr(numsub, 16, __debug_buf, sizeof(__debug_buf));
	bigint_bn_GetStr(object, 16, __debug_buf, sizeof(__debug_buf));
#endif
1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240
	ret = objectCall0(numsub, IsNeg);
retresult:
	objectCall1(numobj, SetUnsigned, isunsignedobj);
	objectCall1(numobj, SetWidth, widthobj);
	objectCall1(numsrc, SetUnsigned, isunsignedsrc);
	objectCall1(numsrc, SetWidth, widthsrc);

	objectRelease(numobj);
	objectRelease(numsrc);
	objectRelease(numsub);
	return ret;
饶先宏's avatar
饶先宏 已提交
1241 1242
}

1243
static int bigint_bn_IsLE(HOBJECT object, HOBJECT src)
饶先宏's avatar
饶先宏 已提交
1244
{
1245
	if (bigint_bn_IsLT(object, src))
1246
		return 1;
1247 1248 1249
	if (bigint_bn_IsEQ(object, src))
		return 1;
	return 0;
饶先宏's avatar
饶先宏 已提交
1250 1251
}

1252
static int bigint_bn_IsEQ(HOBJECT object, HOBJECT src)
饶先宏's avatar
饶先宏 已提交
1253
{
饶先宏's avatar
饶先宏 已提交
1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264
	IBigNumber** numobj;
	IBigNumber** numsrc;
	int ret;

	int i, buflen, widthobj, widthsrc, width, isunsignedobj, isunsignedsrc;

	if (0 != objectQueryInterface(object, IID_BIGNUMBER, &numobj))
		return -1;
	if (0 != objectQueryInterface(src, IID_BIGNUMBER, &numsrc)) {
		objectRelease(numobj);
		return -1;
饶先宏's avatar
饶先宏 已提交
1265
	}
饶先宏's avatar
饶先宏 已提交
1266 1267 1268 1269 1270 1271 1272 1273 1274 1275

	widthobj = objectCall0(numobj, GetWidth);
	widthsrc = objectCall0(numsrc, GetWidth);
	isunsignedobj = objectCall0(numobj, IsUnsigned);
	isunsignedsrc = objectCall0(numsrc, IsUnsigned);

	width = widthobj;
	if (width < widthsrc)
		width = widthsrc;

1276
//	objectCall1(numobj, SetUnsigned, 0);
饶先宏's avatar
饶先宏 已提交
1277
	objectCall1(numobj, SetWidth, width);
1278
//	objectCall1(numsrc, SetUnsigned, 0);
饶先宏's avatar
饶先宏 已提交
1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290
	objectCall1(numsrc, SetWidth, width);

	buflen = (width + 31) / 32;

	for (i = 0; i < buflen; i++) {
		unsigned int srcdata, objdata;
		objectCall2(numobj, GetBits32, i, &objdata);
		objectCall2(numsrc, GetBits32, i, &srcdata);
		if (objdata != srcdata) {
			ret = 0;
			goto retresult;
		}
1291
	}
饶先宏's avatar
饶先宏 已提交
1292 1293 1294 1295 1296 1297 1298 1299 1300 1301
	ret = 1;
retresult:
	objectCall1(numobj, SetUnsigned, isunsignedobj);
	objectCall1(numobj, SetWidth, widthobj);
	objectCall1(numsrc, SetUnsigned, isunsignedsrc);
	objectCall1(numsrc, SetWidth, widthsrc);

	objectRelease(numobj);
	objectRelease(numsrc);
	return ret;
饶先宏's avatar
饶先宏 已提交
1302 1303 1304
}


1305 1306
static int bigint_bn_IsNE(HOBJECT object, HOBJECT src)
{
1307
	return !bigint_bn_IsEQ(object, src);
饶先宏's avatar
饶先宏 已提交
1308 1309
}

1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327
static int bigint_bn_IsZero(HOBJECT object)
{
	sBigInteger* pobj;
	int i;
	pobj = (sBigInteger*)objectThis(object);
	for (i = 0; i < pobj->buflen; i++)
		if (pobj->buf[i] != 0)
			return 0;
	return 1;
}

static int bigint_bn_IsNotZero(HOBJECT object)
{
	sBigInteger* pobj;
	int i;
	pobj = (sBigInteger*)objectThis(object);
	for (i = 0; i < pobj->buflen; i++)
		if (pobj->buf[i] != 0)
饶先宏's avatar
饶先宏 已提交
1328 1329
			return 1;
	return 0;
1330 1331 1332 1333 1334
}

static int bigint_bn_IsNeg(HOBJECT object)
{
	sBigInteger* pobj;
1335 1336 1337
	int bc, sign, signpos;
	if (bigint_bn_IsZero(object))
		return 0;
1338
	pobj = (sBigInteger*)objectThis(object);
1339 1340
	if (pobj->isunsigned)
		return 0;
饶先宏's avatar
饶先宏 已提交
1341
	bc = (pobj->width - 1) / CELL_WIDTH;
1342 1343
	signpos = (pobj->width - 1) % CELL_WIDTH;
	sign = pobj->buf[bc] & (1 << signpos);
1344 1345 1346 1347 1348
	return sign ? 1 : 0;
}

static int bigint_bn_AndL(HOBJECT object, HOBJECT src)
{
1349 1350 1351 1352
	int o, s;
	o = bigint_bn_IsNotZero(object);
	s = bigint_bn_IsNotZero(src);
	return o && s;
1353 1354 1355 1356
}

static int bigint_bn_OrL(HOBJECT object, HOBJECT src)
{
1357 1358 1359 1360
	int o, s;
	o = bigint_bn_IsNotZero(object);
	s = bigint_bn_IsNotZero(src);
	return o || s;
1361 1362 1363 1364
}

static int bigint_bn_NotL(HOBJECT object)
{
1365 1366 1367
	int o;
	o = bigint_bn_IsNotZero(object);
	return !o;
1368 1369 1370 1371
}

static int bigint_bn_And(HOBJECT object, HOBJECT src0, HOBJECT src1)
{
1372 1373 1374 1375 1376 1377 1378
	IBigNumber** numobj;
	IBigNumber** numsrc0;
	IBigNumber** numsrc1;
	int widthobj, widthsrc0, widthsrc1, isunsignedobj, isunsignedsrc0, isunsignedsrc1, width;
	int i, buflen;
	
	if (EIID_OK != objectQueryInterface(object, IID_BIGNUMBER, (void**)&numobj)) {
饶先宏's avatar
饶先宏 已提交
1379 1380
		return -1;
	}
1381 1382
	if (EIID_OK != objectQueryInterface(src0, IID_BIGNUMBER, (void**)&numsrc0)) {
		objectRelease(numobj);
饶先宏's avatar
饶先宏 已提交
1383 1384
		return -1;
	}
1385 1386 1387 1388
	if (EIID_OK != objectQueryInterface(src1, IID_BIGNUMBER, (void**)&numsrc1)) {
		objectRelease(numobj);
		objectRelease(numsrc0);
		return -1;
饶先宏's avatar
饶先宏 已提交
1389
	}
1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412
	widthobj = objectCall0(numobj, GetWidth);
	widthsrc0 = objectCall0(numsrc0, GetWidth);
	widthsrc1 = objectCall0(numsrc1, GetWidth);

	isunsignedobj = objectCall0(numobj, IsUnsigned);
	isunsignedsrc0 = objectCall0(numsrc0, IsUnsigned);
	isunsignedsrc1 = objectCall0(numsrc1, IsUnsigned);

	width = widthobj;
	if (width < widthsrc0)
		width = widthsrc0;
	if (width < widthsrc1)
		width = widthsrc1;

//	objectCall1(numobj, SetUnsigned, 0);
//	objectCall1(numsrc0, SetUnsigned, 0);
//	objectCall1(numsrc1, SetUnsigned, 0);
	objectCall1(numobj, SetWidth, width);
	objectCall1(numsrc0, SetWidth, width);
	objectCall1(numsrc1, SetWidth, width);

	buflen = (width + CELL_WIDTH - 1) / CELL_WIDTH;
	for (i = 0; i < buflen; i++) {
饶先宏's avatar
饶先宏 已提交
1413
		unsigned int src0value, src1value;
1414 1415 1416
		objectCall2(numsrc0, GetBits32, i, &src0value);
		objectCall2(numsrc1, GetBits32, i, &src1value);
		objectCall2(numobj, SetBits32, i, src0value & src1value);
饶先宏's avatar
饶先宏 已提交
1417 1418
	}

1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429
	objectCall1(numobj, SetUnsigned, isunsignedobj);
	objectCall1(numsrc0, SetUnsigned, isunsignedsrc0);
	objectCall1(numsrc1, SetUnsigned, isunsignedsrc1);
	objectCall1(numobj, SetWidth, widthobj);
	objectCall1(numsrc0, SetWidth, widthsrc0);
	objectCall1(numsrc1, SetWidth, widthsrc1);

	objectRelease(numobj);
	objectRelease(numsrc0);
	objectRelease(numsrc1);
	return 0;
1430 1431 1432 1433
}

static int bigint_bn_Or(HOBJECT object, HOBJECT src0, HOBJECT src1)
{
1434 1435 1436 1437 1438 1439 1440
	IBigNumber** numobj;
	IBigNumber** numsrc0;
	IBigNumber** numsrc1;
	int widthobj, widthsrc0, widthsrc1, isunsignedobj, isunsignedsrc0, isunsignedsrc1, width;
	int i, buflen;

	if (EIID_OK != objectQueryInterface(object, IID_BIGNUMBER, (void**)&numobj)) {
1441 1442
		return -1;
	}
1443 1444
	if (EIID_OK != objectQueryInterface(src0, IID_BIGNUMBER, (void**)&numsrc0)) {
		objectRelease(numobj);
饶先宏's avatar
饶先宏 已提交
1445 1446
		return -1;
	}
1447 1448 1449 1450
	if (EIID_OK != objectQueryInterface(src1, IID_BIGNUMBER, (void**)&numsrc1)) {
		objectRelease(numobj);
		objectRelease(numsrc0);
		return -1;
饶先宏's avatar
饶先宏 已提交
1451
	}
1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474
	widthobj = objectCall0(numobj, GetWidth);
	widthsrc0 = objectCall0(numsrc0, GetWidth);
	widthsrc1 = objectCall0(numsrc1, GetWidth);

	isunsignedobj = objectCall0(numobj, IsUnsigned);
	isunsignedsrc0 = objectCall0(numsrc0, IsUnsigned);
	isunsignedsrc1 = objectCall0(numsrc1, IsUnsigned);

	width = widthobj;
	if (width < widthsrc0)
		width = widthsrc0;
	if (width < widthsrc1)
		width = widthsrc1;

//	objectCall1(numobj, SetUnsigned, 0);
//	objectCall1(numsrc0, SetUnsigned, 0);
//	objectCall1(numsrc1, SetUnsigned, 0);
	objectCall1(numobj, SetWidth, width);
	objectCall1(numsrc0, SetWidth, width);
	objectCall1(numsrc1, SetWidth, width);

	buflen = (width + CELL_WIDTH - 1) / CELL_WIDTH;
	for (i = 0; i < buflen; i++) {
饶先宏's avatar
饶先宏 已提交
1475
		unsigned int src0value, src1value;
1476 1477 1478
		objectCall2(numsrc0, GetBits32, i, &src0value);
		objectCall2(numsrc1, GetBits32, i, &src1value);
		objectCall2(numobj, SetBits32, i, src0value | src1value);
饶先宏's avatar
饶先宏 已提交
1479
	}
1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490

	objectCall1(numobj, SetUnsigned, isunsignedobj);
	objectCall1(numsrc0, SetUnsigned, isunsignedsrc0);
	objectCall1(numsrc1, SetUnsigned, isunsignedsrc1);
	objectCall1(numobj, SetWidth, widthobj);
	objectCall1(numsrc0, SetWidth, widthsrc0);
	objectCall1(numsrc1, SetWidth, widthsrc1);

	objectRelease(numobj);
	objectRelease(numsrc0);
	objectRelease(numsrc1);
1491 1492 1493 1494 1495
	return 0;
}

static int bigint_bn_Xor(HOBJECT object, HOBJECT src0, HOBJECT src1)
{
1496 1497 1498 1499 1500 1501 1502
	IBigNumber** numobj;
	IBigNumber** numsrc0;
	IBigNumber** numsrc1;
	int widthobj, widthsrc0, widthsrc1, isunsignedobj, isunsignedsrc0, isunsignedsrc1, width;
	int i, buflen;

	if (EIID_OK != objectQueryInterface(object, IID_BIGNUMBER, (void**)&numobj)) {
1503 1504
		return -1;
	}
1505 1506
	if (EIID_OK != objectQueryInterface(src0, IID_BIGNUMBER, (void**)&numsrc0)) {
		objectRelease(numobj);
饶先宏's avatar
饶先宏 已提交
1507
		return -1;
1508
	}
1509 1510 1511 1512
	if (EIID_OK != objectQueryInterface(src1, IID_BIGNUMBER, (void**)&numsrc1)) {
		objectRelease(numobj);
		objectRelease(numsrc0);
		return -1;
饶先宏's avatar
饶先宏 已提交
1513
	}
1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536
	widthobj = objectCall0(numobj, GetWidth);
	widthsrc0 = objectCall0(numsrc0, GetWidth);
	widthsrc1 = objectCall0(numsrc1, GetWidth);

	isunsignedobj = objectCall0(numobj, IsUnsigned);
	isunsignedsrc0 = objectCall0(numsrc0, IsUnsigned);
	isunsignedsrc1 = objectCall0(numsrc1, IsUnsigned);

	width = widthobj;
	if (width < widthsrc0)
		width = widthsrc0;
	if (width < widthsrc1)
		width = widthsrc1;

//	objectCall1(numobj, SetUnsigned, 0);
//	objectCall1(numsrc0, SetUnsigned, 0);
//	objectCall1(numsrc1, SetUnsigned, 0);
	objectCall1(numobj, SetWidth, width);
	objectCall1(numsrc0, SetWidth, width);
	objectCall1(numsrc1, SetWidth, width);

	buflen = (width + CELL_WIDTH - 1) / CELL_WIDTH;
	for (i = 0; i < buflen; i++) {
饶先宏's avatar
饶先宏 已提交
1537
		unsigned int src0value, src1value;
1538 1539 1540
		objectCall2(numsrc0, GetBits32, i, &src0value);
		objectCall2(numsrc1, GetBits32, i, &src1value);
		objectCall2(numobj, SetBits32, i, src0value ^ src1value);
饶先宏's avatar
饶先宏 已提交
1541
	}
1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552

	objectCall1(numobj, SetUnsigned, isunsignedobj);
	objectCall1(numsrc0, SetUnsigned, isunsignedsrc0);
	objectCall1(numsrc1, SetUnsigned, isunsignedsrc1);
	objectCall1(numobj, SetWidth, widthobj);
	objectCall1(numsrc0, SetWidth, widthsrc0);
	objectCall1(numsrc1, SetWidth, widthsrc1);

	objectRelease(numobj);
	objectRelease(numsrc0);
	objectRelease(numsrc1);
1553 1554 1555 1556 1557
	return 0;
}

static int bigint_bn_Not(HOBJECT object, HOBJECT src)
{
1558 1559 1560 1561 1562 1563
	IBigNumber** numobj;
	IBigNumber** numsrc;
	int widthobj, widthsrc, isunsignedobj, isunsignedsrc, width;
	int i, buflen;

	if (EIID_OK != objectQueryInterface(object, IID_BIGNUMBER, (void**)&numobj)) {
饶先宏's avatar
饶先宏 已提交
1564 1565
		return -1;
	}
1566 1567 1568
	if (EIID_OK != objectQueryInterface(src, IID_BIGNUMBER, (void**)&numsrc)) {
		objectRelease(numobj);
		return -1;
饶先宏's avatar
饶先宏 已提交
1569
	}
1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586
	widthobj = objectCall0(numobj, GetWidth);
	widthsrc = objectCall0(numsrc, GetWidth);

	isunsignedobj = objectCall0(numobj, IsUnsigned);
	isunsignedsrc = objectCall0(numsrc, IsUnsigned);

	width = widthobj;
	if (width < widthsrc)
		width = widthsrc;

//	objectCall1(numobj, SetUnsigned, 0);
//	objectCall1(numsrc, SetUnsigned, 0);
	objectCall1(numobj, SetWidth, width);
	objectCall1(numsrc, SetWidth, width);

	buflen = (width + CELL_WIDTH - 1) / CELL_WIDTH;
	for (i = 0; i < buflen; i++) {
饶先宏's avatar
饶先宏 已提交
1587
		unsigned int srcvalue;
1588 1589
		objectCall2(numsrc, GetBits32, i, &srcvalue);
		objectCall2(numobj, SetBits32, i, ~srcvalue);
饶先宏's avatar
饶先宏 已提交
1590
	}
1591 1592 1593 1594 1595 1596 1597 1598

	objectCall1(numobj, SetUnsigned, isunsignedobj);
	objectCall1(numsrc, SetUnsigned, isunsignedsrc);
	objectCall1(numobj, SetWidth, widthobj);
	objectCall1(numsrc, SetWidth, widthsrc);

	objectRelease(numobj);
	objectRelease(numsrc);
1599 1600 1601 1602 1603 1604
	return 0;
}

static int bigint_bn_uAnd(HOBJECT object, HOBJECT src)
{
	sBigInteger* pobj;
1605 1606 1607
	IBigNumber** numsrc;
	IBigNumber** temp;
	int width;
1608
	pobj = (sBigInteger*)objectThis(object);
1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623
	if (EIID_OK != objectQueryInterface(src, IID_BIGNUMBER, (void**)&numsrc)) {
		return -1;
	}
	width = objectCall0(numsrc, GetWidth);
	temp = bigintegerCreate(width);
	objectCall1(temp, SetUnsigned, 1);
	objectCall1(temp, Not, src);
	if (objectCall0(temp, IsZero)) {
		bigint_bn_AssignUint32(object, 1);
	}
	else {
		bigint_bn_AssignUint32(object, 0);
	}
	objectRelease(numsrc);
	objectRelease(temp);
1624 1625 1626 1627 1628
	return 0;
}

static int bigint_bn_uAndNot(HOBJECT object, HOBJECT src)
{
1629 1630 1631 1632 1633 1634 1635
	bigint_bn_uAnd(object, src);
	if (bigint_bn_IsZero(object)) {
		bigint_bn_AssignUint32(object, 1);
	}
	else {
		bigint_bn_AssignUint32(object, 0);
	}
1636 1637 1638 1639 1640 1641
	return 0;
}

static int bigint_bn_uOr(HOBJECT object, HOBJECT src)
{
	sBigInteger* pobj;
饶先宏's avatar
饶先宏 已提交
1642
	IBigNumber** psrc;
1643
	pobj = (sBigInteger*)objectThis(object);
饶先宏's avatar
饶先宏 已提交
1644 1645 1646 1647
	if (EIID_OK != objectQueryInterface(src, IID_BIGNUMBER, (void**)&psrc)) {
		return -1;
	}
	if (objectCall0(psrc, IsZero)) {
1648
		bigint_bn_AssignUint32(object, 0);
饶先宏's avatar
饶先宏 已提交
1649 1650
	}
	else {
1651
		bigint_bn_AssignUint32(object, 1);
饶先宏's avatar
饶先宏 已提交
1652
	}
1653
	objectRelease(psrc);
1654 1655 1656 1657 1658
	return 0;
}

static int bigint_bn_uOrNot(HOBJECT object, HOBJECT src)
{
1659 1660 1661 1662 1663 1664 1665
	bigint_bn_uOr(object, src);
	if (bigint_bn_IsZero(object)) {
		bigint_bn_AssignUint32(object, 1);
	}
	else {
		bigint_bn_AssignUint32(object, 0);
	}
1666 1667 1668 1669 1670
	return 0;
}

static int bigint_bn_uXor(HOBJECT object, HOBJECT src)
{
1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681
	bigint_bn_uAnd(object, src);
	if (bigint_bn_IsNotZero(object)) {
		bigint_bn_AssignInt32(object, 0);
		return 0;
	}
	bigint_bn_uOr(object, src);
	if (bigint_bn_IsZero(object)) {
		bigint_bn_AssignInt32(object, 0);
		return 0;
	}
	bigint_bn_AssignInt32(object, 1);
1682 1683 1684 1685 1686
	return 0;
}

static int bigint_bn_uXorNot(HOBJECT object, HOBJECT src)
{
1687 1688 1689 1690 1691 1692 1693
	bigint_bn_uXor(object, src);
	if (bigint_bn_IsZero(object)) {
		bigint_bn_AssignUint32(object, 1);
	}
	else {
		bigint_bn_AssignUint32(object, 0);
	}
1694 1695 1696 1697 1698 1699
	return 0;
}

static int bigint_bn_SHL(HOBJECT object, HOBJECT src, int bits)
{ 
	sBigInteger* pobj;
饶先宏's avatar
饶先宏 已提交
1700 1701
	IBigNumber** psrc;
	int widthobj, widthsrc;
1702 1703
	int ifrom, ito, i;
	unsigned long long current, next;
饶先宏's avatar
饶先宏 已提交
1704

饶先宏's avatar
饶先宏 已提交
1705 1706
	if (bits == 0) {
		bigint_bn_Assign(object, src);
1707
		return 0;
饶先宏's avatar
饶先宏 已提交
1708
	}
饶先宏's avatar
饶先宏 已提交
1709

1710 1711
	if (bits < 0)
		return bigint_bn_SHR(object, src, -bits);
饶先宏's avatar
饶先宏 已提交
1712 1713 1714 1715 1716 1717 1718 1719

	pobj = (sBigInteger*)objectThis(object);
	if (EIID_OK != objectQueryInterface(src, IID_BIGNUMBER, (void**)&psrc)) {
		return -1;
	}
	widthobj = pobj->width;
	widthsrc = objectCall0(psrc, GetWidth);
	if (widthsrc < widthobj) {
饶先宏's avatar
饶先宏 已提交
1720
		objectCall1(psrc, SetWidth, widthobj);
饶先宏's avatar
饶先宏 已提交
1721 1722
	}
	else {
饶先宏's avatar
饶先宏 已提交
1723
		objectCall1(psrc, SetWidth, widthsrc);
饶先宏's avatar
饶先宏 已提交
1724 1725
	}

1726 1727 1728 1729 1730 1731
	ito = bits / CELL_WIDTH;
	bits -= ito * CELL_WIDTH;
	ifrom = 0;
	for (i = pobj->buflen-1; i>=0; i--) {
		current = 0;
		if (i >= ito) {
饶先宏's avatar
饶先宏 已提交
1732 1733 1734
			unsigned int srcvalue;
			objectCall2(psrc, GetBits32, i-ito, &srcvalue);
			current = srcvalue;
1735 1736 1737
			current <<= CELL_WIDTH;
		}
		if (i >= ito+1) {
饶先宏's avatar
饶先宏 已提交
1738 1739 1740
			unsigned int srcvalue;
			objectCall2(psrc, GetBits32, i - ito - 1, &srcvalue);
			next = srcvalue;
1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751
			current |= next;
		}
		current >>= CELL_WIDTH - bits;
		pobj->buf[i] = (unsigned int)(current & CELL_MASK);
	}
	return 0;
}

static int bigint_bn_SHR(HOBJECT object, HOBJECT src, int bits)
{
	sBigInteger* pobj;
饶先宏's avatar
饶先宏 已提交
1752 1753 1754
	IBigNumber** psrc;
	unsigned int srcvalue;
	int widthobj, widthsrc;
1755 1756 1757 1758
	int bc;
	int ifrom, ito, i, zerolen;
	unsigned long long current, next;
	pobj = (sBigInteger*)objectThis(object);
饶先宏's avatar
饶先宏 已提交
1759 1760
	if (bits == 0) {
		bigint_bn_Assign(object, src);
1761
		return 0;
饶先宏's avatar
饶先宏 已提交
1762
	}
1763 1764
	if (bits < 0)
		return bigint_bn_SHL(object, src, -bits);
饶先宏's avatar
饶先宏 已提交
1765 1766 1767 1768 1769 1770
	if (EIID_OK != objectQueryInterface(src, IID_BIGNUMBER, (void**)&psrc)) {
		return -1;
	}
	widthobj = pobj->width;
	widthsrc = objectCall0(psrc, GetWidth);
	if (widthsrc < widthobj) {
饶先宏's avatar
饶先宏 已提交
1771
		objectCall1(psrc, SetWidth, widthobj);
饶先宏's avatar
饶先宏 已提交
1772 1773
	}
	else {
饶先宏's avatar
饶先宏 已提交
1774
		objectCall1(psrc, SetWidth, widthsrc);
饶先宏's avatar
饶先宏 已提交
1775
	}
1776 1777
	ito = 0;
	ifrom = bits / CELL_WIDTH;
饶先宏's avatar
饶先宏 已提交
1778 1779
	if (bits >= widthsrc) {
		for (i = 0;i<pobj->buflen;i++)
饶先宏's avatar
饶先宏 已提交
1780
			pobj->buf[i] = pobj->isunsigned?0:CELL_MASK;
1781 1782 1783 1784
		return 0;
	}
	bits -= ifrom * CELL_WIDTH;
	if (ifrom+1 < pobj->buflen) {
饶先宏's avatar
饶先宏 已提交
1785 1786
		objectCall2(psrc, GetBits32, ifrom + 1, &srcvalue);
		current = srcvalue;
1787 1788 1789 1790 1791
		current <<= CELL_WIDTH;
	}
	else {
		current = 0;
	}
饶先宏's avatar
饶先宏 已提交
1792 1793
	objectCall2(psrc, GetBits32, ifrom, &srcvalue);
	current |= srcvalue;
1794 1795 1796 1797
	current >>= bits;
	for (i = ifrom + 1; i < pobj->buflen-1; i++) {
		pobj->buf[ito++] = (unsigned int)(current & CELL_MASK);
		current >>= CELL_WIDTH;
饶先宏's avatar
饶先宏 已提交
1798 1799
		objectCall2(psrc, GetBits32, ifrom, &srcvalue);
		next = srcvalue;
1800 1801 1802 1803
		next <<= CELL_WIDTH-bits;
		current |= next;
	}
	pobj->buf[ito++] = (unsigned int)(current & CELL_MASK);
1804 1805 1806 1807 1808
	current >>= CELL_WIDTH;
	while (ito < pobj->buflen) {
		pobj->buf[ito++] = current;
		current >>= CELL_WIDTH;
	}
1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819
	return 0;
}

static int bigint_bn_SAL(HOBJECT object, HOBJECT src, int bits)
{
	return bigint_bn_SHL(object, src, bits);
}

static int bigint_bn_SAR(HOBJECT object, HOBJECT src, int bits)
{
	sBigInteger* pobj;
饶先宏's avatar
饶先宏 已提交
1820 1821 1822
	IBigNumber** psrc;
	unsigned int srcvalue;
	int widthobj, widthsrc;
1823 1824 1825 1826
	int bc, sign;
	int ifrom, ito, i, zerolen;
	unsigned long long current, next;
	pobj = (sBigInteger*)objectThis(object);
饶先宏's avatar
饶先宏 已提交
1827 1828 1829 1830
	if (bits == 0) {
		if (object != src)
			return bigint_bn_Clone(object, src);
	}
1831 1832
	if (bits < 0)
		return bigint_bn_SHL(object, src, -bits);
饶先宏's avatar
饶先宏 已提交
1833 1834 1835 1836 1837 1838
	if (EIID_OK != objectQueryInterface(src, IID_BIGNUMBER, (void**)&psrc)) {
		return -1;
	}
	widthobj = pobj->width;
	widthsrc = objectCall0(psrc, GetWidth);
	if (widthsrc < widthobj) {
饶先宏's avatar
饶先宏 已提交
1839
		objectCall1(psrc, SetWidth, widthobj);
饶先宏's avatar
饶先宏 已提交
1840 1841
	}
	else {
饶先宏's avatar
饶先宏 已提交
1842
		objectCall1(psrc, SetWidth, widthsrc);
饶先宏's avatar
饶先宏 已提交
1843
	}
1844
	bc = pobj->width / CELL_WIDTH;
饶先宏's avatar
饶先宏 已提交
1845 1846
	objectCall2(psrc, GetBits32, bc, &srcvalue);
	sign = srcvalue & (1 << ((pobj->width-1) & (CELL_WIDTH - 1)));
1847 1848 1849 1850 1851 1852 1853 1854 1855
	ito = 0;
	ifrom = bits / CELL_WIDTH;
	if (ifrom >= pobj->buflen) {
		for (i = 0;i<pobj->buflen;i++)
			pobj->buf[i] = sign ? CELL_MASK : 0;
		return 0;
	}
	bits -= ifrom * CELL_WIDTH;
	if (ifrom + 1 < pobj->buflen) {
饶先宏's avatar
饶先宏 已提交
1856 1857
		objectCall2(psrc, GetBits32, ifrom+1, &srcvalue);
		current = srcvalue;
1858 1859 1860 1861 1862
		current <<= CELL_WIDTH;
	}
	else {
		current = 0;
	}
饶先宏's avatar
饶先宏 已提交
1863 1864
	objectCall2(psrc, GetBits32, ifrom, &srcvalue);
	current |= srcvalue;
1865 1866 1867 1868
	current >>= bits;
	for (i = ifrom + 1; i < pobj->buflen - 1; i++) {
		pobj->buf[ito++] = (unsigned int)(current & CELL_MASK);
		current >>= CELL_WIDTH;
饶先宏's avatar
饶先宏 已提交
1869 1870
		objectCall2(psrc, GetBits32, i + 1, &srcvalue);
		next = srcvalue;
1871 1872 1873 1874 1875 1876 1877 1878 1879
		next <<= CELL_WIDTH - bits;
		current |= next;
	}
	next = sign ? CELL_MASK : 0;
	next <<= CELL_WIDTH - bits;
	current |= next;
	pobj->buf[ito++] = (unsigned int)(current & CELL_MASK);
	while (ito < pobj->buflen)
		pobj->buf[ito++] = sign ? CELL_MASK : 0;
饶先宏's avatar
饶先宏 已提交
1880 1881 1882
	return 0;
}

饶先宏's avatar
饶先宏 已提交
1883
IBigNumber** bigintegerCreate(int width)
饶先宏's avatar
饶先宏 已提交
1884 1885 1886
{
	int ret;
	IBigNumber** bn;
饶先宏's avatar
饶先宏 已提交
1887
	PARAMITEM param;
饶先宏's avatar
饶先宏 已提交
1888
	A_u_t_o_registor_bigint();
饶先宏's avatar
饶先宏 已提交
1889 1890 1891
	param.name = PARAMID_BIGINTEGERWIDTH;
	param.i32value = width;
	ret = objectCreateEx(CLSID_BIGINTEGER, &param, 1, IID_BIGNUMBER, (const void**)&bn);
饶先宏's avatar
饶先宏 已提交
1892 1893
	return bn;
}